Python 用最后有效值的百分比填充nan-s

Python 用最后有效值的百分比填充nan-s,python,pandas,Python,Pandas,我有一个dataframe,其中的列包含NaN值。我想用值填充这些。带有方法“ffill”的Fillna()几乎是我想要的,但不完全是。我希望最后有效值的120%替换我的NAN。因此,如果NaN之前的最后一个有效值是100.0,那么我希望NaN的位置是120.0 我知道我可以迭代我的df,但那需要很多时间。(我的df现在大约有100000行,并将进一步增加) 例如: df是我的初始数据帧: df=pd.DataFrame([[np.nan,2,np.nan,0],[3,4,np.nan,1],[

我有一个dataframe,其中的列包含NaN值。我想用值填充这些。带有方法“ffill”的Fillna()几乎是我想要的,但不完全是。我希望最后有效值的120%替换我的NAN。因此,如果NaN之前的最后一个有效值是100.0,那么我希望NaN的位置是120.0

我知道我可以迭代我的df,但那需要很多时间。(我的df现在大约有100000行,并将进一步增加)

例如: df是我的初始数据帧:

df=pd.DataFrame([[np.nan,2,np.nan,0],[3,4,np.nan,1],[np.nan,np.nan,np.nan,np.nan,5],[np.nan,3,np.nan,4],[np.nan,3,np.nan,4],[columns=list('ABCD'))

这就是我想要得到的:

>>> df
    A    B    C    D
0  NaN  2.0  NaN  0.0
1  3.0  4.0  NaN  1.0
2  3.6  NaN  NaN  5.0
3  3.6  3.0  NaN  4.0
4  5.0  4.0  2.0  NaN
5  6.0  3.0  NaN  4.0
因此,列“A”在第2行和第3行中有两个替换项,它们现在的值都是3.6(3*1.2),而不是NaN,再加上第5行的变化,NaN被替换为6(5*1.2)
一开始我不在乎南斯,他们可以留下来。我只想在列“A”中进行更改。我建议您使用一个部分列,检查在
ffill

详情如下:

df['partially_filled_A'] = df['A'].fillna(method='ffill')
df['isNan'] = df['A'].isnull()

df['A_filled'] = np.where((df['isNan']) & (df['partially_filled_A'].isnull() == False), df['partially_filled_A']*1.2, df['A'])

df
我与
iteritems
进行了一些比较,结果如下:

df = pd.concat([df for _ in range(500_000)]) # let's make a df with 3_000_000 rows for the benchmark
使用iteritems 使用
np.where

正如在这个快速基准测试中所看到的,我强烈建议您使用
np。在

中,您应该提供一个“输入”和“期望输出”,我不知道是否所有有效值都在nan之前,如果它们被洗牌,则是。如果第一个值是nan会发生什么?感谢您的反馈BlueSheepToken,问题会根据您的请求进行更新。非常感谢,它更清晰了!我会试着看一看。(不幸的是,我不太擅长熊猫,我会尝试寻找窗口功能的等价物)非常感谢!这是我所期待的!我只尝试了np.where方法,因为根据您的基准测试,它速度更快,而且代码更短、更好。做了我想做的事。
df = pd.concat([df for _ in range(500_000)]) # let's make a df with 3_000_000 rows for the benchmark
%% time
l = []
last_value = None
for item, frame in df['A'].iteritems():
    if last_value is None:
        if pd.notnull(frame):
            last_value = frame * 1.2
            l.append(frame)
        else:
            l.append(np.nan)
    else:
        if pd.notnull(frame):
            l.append(frame)
            last_value = frame * 1.2
        else:
            l.append(last_value)
df['ans'] = l
# 2.5 seconds
%%time
df['partially_filled_A'] = df['A'].fillna(method='ffill')
df['isNan'] = df['A'].isnull()

df['A_filled'] = np.where((df['isNan']) & (df['partially_filled_A'].isnull() == False), df['partially_filled_A']*1.2, df['A'])
#100 ms