Erwin109
Erwin109

Reputation: 17

df.apply return NaN in pandas dataframe

I am trying to fill up a column in a dataframe with 1, 0 or -1 depending on some factors by doing it like this:

def set_order_signal(row):
    
    if (row.MACD > row.SIGNAL) and (df.iloc[i-1].MACD < df.iloc[i-1].SIGNAL):
        if (row.MACD < 0 and row.SIGNAL < 0) and (row.close > row['200EMA']): 
            return 1
            
    elif (row.MACD < row.SIGNAL) and (df.iloc[i-1].MACD > df.iloc[i-1].SIGNAL):
        if (row.MACD > 0 and row.SIGNAL > 0) and (row.close < row['200EMA']):
            return -1
    else:
        return 0

Sometimes it works but in other rows it returns "NaN". I can't find a reason or solution for this.

The dataframe I work with looks like this:

time    open    high    low close   tick_volume spread  real_volume EMA_LONG    EMA_SHORT   MACD    SIGNAL  HIST    200EMA  OrderSignal
0   2018-01-09 05:00:00 1.19726 1.19751 1.19675 1.19717 1773    1   0   1.197605    1.197152    -0.000453   -0.000453   0.000000e+00    1.197170    0.0
1   2018-01-09 06:00:00 1.19717 1.19724 1.19659 1.19681 1477    1   0   1.197538    1.197099    -0.000439   -0.000445   6.258599e-06    1.196989    0.0
2   2018-01-09 07:00:00 1.19681 1.19718 1.19642 1.19651 1622    1   0   1.197452    1.197008    -0.000444   -0.000445   5.327180e-07    1.196828    0.0
3   2018-01-09 08:00:00 1.19650 1.19650 1.19518 1.19560 3543    1   0   1.197298    1.196789    -0.000509   -0.000466   -4.237181e-05   1.196516    NaN

I'm trying to apply it to the df with this:

df['OrderSignal'] = df.apply(set_order_signal, axis=1)

Is it a format problem?

Thank you already!

Upvotes: 0

Views: 898

Answers (1)

Jonathan Leon
Jonathan Leon

Reputation: 5648

If you are looking for the index of the row that is sent to function, you need to use row.name, not i.

Try this and see what you get for your results. Can't tell if the logic is correct in all cases, but the four rows returns 0 each time

def set_order_signal(row):
    if (row.MACD > row.SIGNAL) and (df.iloc[row.name-1].MACD < df.iloc[row.name-1].SIGNAL):
        if (row.MACD < 0 and row.SIGNAL < 0) and (row.close > row['200EMA']): 
            return 1
            
    elif (row.MACD < row.SIGNAL) and (df.iloc[row.name-1].MACD > df.iloc[row.name-1].SIGNAL):
        if (row.MACD > 0 and row.SIGNAL > 0) and (row.close < row['200EMA']):
            return -1
    else:
        return 0

Upvotes: 1

Related Questions