Write custom fillna function in pandas dataframe to fill np.nan with different values ​​with conditions

Given the following pandas framework:

import pandas as pd

change = [0.475, 0.625, 0.1, 0.2, -0.1, -0.75, 0.1, -0.1, 0.2, -0.2]
position = [1.0, 1.0, nan, nan, nan, -1.0, nan, nan, nan, nan]
date = ['20150101', '20150102', '20150103', '20150104', '20150105', '20150106', '20150107', '20150108', '20150109', '20150110']
pd.DataFrame({'date': date, 'position': position, 'change': change})

Outputs

     date        change       position    
    20150101      0.475          1
    20150102      0.625          1
    20150103      0.1            np.nan
    20150104      0.2            np.nan
    20150105      -0.1           np.nan
    20150106      -0.75          -1
    20150107      0.1            np.nan
    20150108      -0.1           np.nan
    20150109      0.2            np.nan
    20150110      -0.2           np.nan

I want to fill out the following rules:

  • For lines whose "position" has the value np.nan, if the value of "change" has the same sign of the last non-zero value of the position (change * position> 0, for example, 0.1 * 1 and 0.2 * 1> 0), we fill in the last nonzero value.

  • For strings whose position value is np.nan, if the change value has the same sign of the last nonzero value of the position value (change * position <= 0, for example -1 * 0.1), we fill in 0.

  • As soon as one np.nan is filled with 0, the next np.nan will also be filled with 0.

The following are the expected results from the sample frame:

     date        change       position    
    20150101      0.475          1
    20150102      0.625          1
    20150103      0.1            1
    20150104      0.2            1
    20150105      -0.1           0
    20150106      -0.75          -1
    20150107      0.1            0
    20150108      -0.1           0
    20150109      0.2            0
    20150110      -0.2           0

EDIT:

, , :

while(any(np.isnan(x['position']))):
    conditions = [(np.isnan(x['position'])) & (x['position'].shift(1) * x['change'] > 0),
                  (np.isnan(x['position'])) & (x['position'].shift(1) * x['change'] <= 0)]
    choices = [x['position'].shift(1), 0]
    x['position'] = np.select(conditions, choices, default=x['position'])

, , , 80 000 000 .

? !

+4
1

, , , , . shift() , fillna(method='ffill'), , , ( ).

conditions = [
    (np.isnan(x['position'])) & (x['position'].fillna(method='ffill')*x['change']>0),
    (np.isnan(x['position'])) & (x['position'].fillna(method='ffill')*x['change']<=0)]

, while, fillna :

conditions = [
    (np.isnan(x['position'])) & (x['position'].fillna(method='ffill')*x['change']>0),
    (np.isnan(x['position'])) & (x['position'].fillna(method='ffill')*x['change']<=0)]

choices=[x['position'].shift(1),0]
x['position'] = np.select(conditions,choices,default=x['position'])

x['position'] = x['position'].fillna(method='ffill')

2 , - 4 . , , , , , .

+3

All Articles