Python pandas ffil和bfill基于groupby条件
每列Python pandas ffil和bfill基于groupby条件,python,pandas,dataframe,Python,Pandas,Dataframe,每列col1、col2和col3都需要在列col4上设置向前或向后填充条件 假设我有这样一个数据帧: df = pd.DataFrame({'col1':[1,np.nan,3, np.nan,5,np.nan], 'col2':[7, np.nan, 9, np.nan, 11, np.nan], 'col3':[13, 14, 15, 16, np.nan,18],
col1
、col2
和col3
都需要在列col4
上设置向前或向后填充条件
假设我有这样一个数据帧:
df = pd.DataFrame({'col1':[1,np.nan,3, np.nan,5,np.nan],
'col2':[7, np.nan, 9, np.nan, 11, np.nan],
'col3':[13, 14, 15, 16, np.nan,18],
'col4':[2015, 2015, 2015, 2016, 2016, 2018]})
col1 col2 col3 col4
0 1.0 7.0 13.0 2015
1 NaN NaN 14.0 2015
2 3.0 9.0 15.0 2015
3 NaN NaN 16.0 2016
4 5.0 11.0 NaN 2016
5 NaN NaN 18.0 2018
我正试图通过groupby实现这一点
grouped = df.groupby('col4')
然后我在组上循环,如果组名满足条件,我会进行填充(向后或向前)并更新数据帧
for name, group in grouped:
if name == 2015:
df[df.col4==name][['col1', 'col2']] = grouped.get_group(name)[['col1', 'col2']].ffill(axis=0)
elif name == 2016:
df[df.col4==name]['col1'] = grouped.get_group(name)['col1'].ffill(axis=0)
df[df.col4==name][['col2', 'col3']] = grouped.get_group(name)[['col1', 'col2']].bfill(axis=0)
else:
df[df.col4==name]['col1', 'col2', 'col3'] = grouped.get_group(name)['col1'].bfill(axis=0)
但是,这不起作用,而且看起来很长。看起来很像
如果您有任何建议,我将不胜感激。您的问题不清楚。例如,您没有在循环中说明2018年。我们用它做什么。如果你只需要2015年和2016年。请试一试
m=df.col4 ==2015#Boolean select
df.loc[m,'col1':'col3']=df.loc[m,'col1':'col3'].fillna(method='ffill')#Forward Fill
df.loc[~m,'col1':'col3']=df.loc[~m,'col1':'col3'].fillna(method='bfill').fillna(method='ffill')
col1 col2 col3 col4
0 1.0 7.0 13.0 2015
1 1.0 7.0 14.0 2015
2 3.0 9.0 15.0 2015
3 5.0 11.0 16.0 2016
4 5.0 11.0 18.0 2016
5 5.0 11.0 18.0 2018
根据所有建议,我解决了这个问题如下:
for name, group in grouped:
if name == 2015:
df.loc[df.col4==name, ['col1', 'col2']] = grouped.get_group(name)[['col1', 'col2']].ffill(axis=0)
elif name == 2016:
df.loc[df.col4==name, ['col1']] = grouped.get_group(name)['col1'].ffill(axis=0)
df.loc[df.col4==name, ['col2', 'col3']] = grouped.get_group(name)[['col1', 'col2']].bfill(axis=0)
else:
df[df.col4==name, ['col1', 'col2', 'col3']] = grouped.get_group(name)['col1'].bfill(axis=0)
你能编辑你的问题并把预期的结果放在那里吗?
df[df.col4==name][[col1',col2']
是索引链接,使用df.loc[df.col4==name,['col1',col2']
代替。谢谢!你说得对,我增加了2018年的额外声明。事实上,我在col4中有很多值,这只是一个例子。这是一项调查,观察者在某些年份只填写起始值或结束值。这应该可以解释问题的背景。您的答案几乎是正确的,如果您对不同级别的分组变量(循环?)进行了更改,我将接受它为正确的。再次感谢你的帮助!请尝试df[['col1','col2']]=df.groupby((df.col1.notna()| df.col2.notna()).cumsum())[['col1',col2']]].fillna(method='ffill')
。那么col3
中的情况如何,即NaN
。你的解释似乎没有抓住这一点。