[英]Forward Fill Pandas Dataframe Horizontally (along rows) without forward filling last value in each row
我有一个Pandas数据框,我想转发填充HORIZONTALLY但我不想转发填写每行的最后一个条目。 这是关于某些产品已停产的产品的时间序列定价数据,因此我不希望记录的最后一个值向前填充到当前。
FWDFILL.apply(lambda series: series.iloc[:,series.last_valid_index()].ffill(axis=1))
^我所包含的代码做了我想要的但是它是垂直的。 这可能可以帮助人们作为起点。
>>> print(FWDFILL)
1 1 NaN NaN 2 NaN
2 NaN 1 NaN 5 NaN
3 NaN 3 1 NaN NaN
4 NaN NaN NaN NaN NaN
5 NaN 5 NaN NaN 1
期望的输出:
1 1 1 1 2 NaN
2 NaN 1 1 5 NaN
3 NaN 3 1 NaN NaN
4 NaN NaN NaN NaN NaN
5 NaN 5 5 5 1
在IIUC中,您需要apply
axis=1
,因此您将应用于数据帧行而不是数据帧列。
df.apply(lambda x: x[:x.last_valid_index()].ffill(), axis=1)
输出:
1 2 3 4 5
0
1 1.0 1.0 1.0 2.0 NaN
2 NaN 1.0 1.0 5.0 NaN
3 NaN 3.0 1.0 NaN NaN
4 NaN NaN NaN NaN NaN
5 NaN 5.0 5.0 5.0 1.0
您可以使用numpy
查找最后的有效索引并屏蔽您的ffill
。 这允许您使用矢量化ffill
,然后使用矢量化蒙版。
u = df.values
m = (~np.isnan(u)).cumsum(1).argmax(1)
df.ffill(1).mask(np.arange(df.shape[0]) > m[:, None])
0 1 2 3 4
0 1.0 1.0 1.0 2.0 NaN
1 NaN 1.0 1.0 5.0 NaN
2 NaN 3.0 1.0 NaN NaN
3 NaN NaN NaN NaN NaN
4 NaN 5.0 5.0 5.0 1.0
信息
>>> np.arange(df.shape[0]) > m[:, None]
array([[False, False, False, False, True],
[False, False, False, False, True],
[False, False, False, True, True],
[False, True, True, True, True],
[False, False, False, False, False]])
使用bfill
和ffill
s1=df.ffill(1)
s2=df.bfill(1)
df=df.mask(s1.notnull()&s2.notnull(),s1)
df
Out[222]:
1 2 3 4 5
1 1.0 1.0 1.0 2.0 NaN
2 NaN 1.0 1.0 5.0 NaN
3 NaN 3.0 1.0 NaN NaN
4 NaN NaN NaN NaN NaN
5 NaN 5.0 5.0 5.0 1.0
或者只是使用interpolate
df.mask(df.interpolate(axis=1,limit_area='inside').notnull(),df.ffill(1))
Out[226]:
1 2 3 4 5
1 1.0 1.0 1.0 2.0 NaN
2 NaN 1.0 1.0 5.0 NaN
3 NaN 3.0 1.0 NaN NaN
4 NaN NaN NaN NaN NaN
5 NaN 5.0 5.0 5.0 1.0
很少修改 - Most efficient way to forward-fill NaN values in numpy array
的解决方案中Most efficient way to forward-fill NaN values in numpy array
这里解决它 -
def ffillrows_stoplast(arr):
# Identical to earlier solution of forward-filling
mask = np.isnan(arr)
idx = np.where(~mask,np.arange(mask.shape[1]),0)
idx_acc = np.maximum.accumulate(idx,axis=1)
out = arr[np.arange(idx.shape[0])[:,None], idx_acc]
# Perform flipped index accumulation to get trailing NaNs mask and
# accordingly assign NaNs there
out[np.maximum.accumulate(idx[:,::-1],axis=1)[:,::-1]==0] = np.nan
return out
样品运行 -
In [121]: df
Out[121]:
A B C D E
1 1.0 NaN NaN 2.0 NaN
2 NaN 1.0 NaN 5.0 NaN
3 NaN 3.0 1.0 NaN NaN
4 NaN NaN NaN NaN NaN
5 NaN 5.0 NaN NaN 1.0
In [122]: out = ffillrows_stoplast(df.to_numpy())
In [123]: pd.DataFrame(out,columns=df.columns,index=df.index)
Out[123]:
A B C D E
1 1.0 1.0 1.0 2.0 NaN
2 NaN 1.0 1.0 5.0 NaN
3 NaN 3.0 1.0 NaN NaN
4 NaN NaN NaN NaN NaN
5 NaN 5.0 5.0 5.0 1.0
我想在ffill
上使用where
可以回到那些在bfill
上被忽略的NaN
df.ffill(1).where(df.bfill(1).notna())
Out[1623]:
a b c d e
1 1.0 1.0 1.0 2.0 NaN
2 NaN 1.0 1.0 5.0 NaN
3 NaN 3.0 1.0 NaN NaN
4 NaN NaN NaN NaN NaN
5 NaN 5.0 5.0 5.0 1.0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.