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