我有这样的数据帧:
df = pd.DataFrame({'Event': ['A', 'B', 'A', 'A', 'B', 'C', 'B', 'B', 'A', 'C'],
'Direction': ['UP', 'DOWN', 'UP', 'UP', 'DOWN', 'DOWN', 'DOWN', 'UP', 'DOWN', 'UP'],
'group':[1,2,3,3,3,4,4,4,5,5]})
一切都很好,当我这样做的时候:
df['prev'] = df[(df.Event == 'A') & (df.Direction == 'UP')].groupby('group').cumcount().add(1)
df['prev'].fillna(0, inplace=True)
但如果我在一行中完成,fillna((函数将不起作用:
df['prev'] = df[(df.Event == 'A') & (df.Direction == 'UP')].groupby('group').cumcount().add(1).fillna(0)
我的问题是:为什么?有没有一种方法可以做到这一点?
看看这一步的输出:
print(df[(df.Event == 'A') & (df.Direction == 'UP')].groupby('group').cumcount().add(1))
# Output:
0 1
2 1
3 2
dtype: int64
您看到要填充的nan
值了吗?在这里添加.fillna(0)
有什么作用吗?
一个可以工作的内衬:
df['prev'] = df.assign(prev = df[(df.Event == 'A') & (df.Direction == 'UP')].groupby('group').cumcount().add(1))['prev'].fillna(0)
因为这部分df[(df.Event == 'A') & (df.Direction == 'UP')]
只过滤事件A
和方向UP
的行,所以当你把fillna(0)
放在最后时,你只替换了过滤的行子集中的NaN
,其余的将用NaN
填充,因为列prev
以前不存在。
另外,因为列prev
以前并不存在,所以我认为您不能在一行中完成此操作。您要做的是创建一整列,只修改同一列的一个子集,您必须分两步将其打断。
我不确定它为什么不起作用,但我有一个大致的想法。在你的第一个想法中,这就是正在发生的事情:
df['prev'] = df[...]...
df['prev'] = df['prev'].fillna(0)
你的第二个想法:
df['prev'] = df[...]....fillna(0)
这可能与将fillna(0)
放在整个数据帧上有关,当转移到新的变量(列(prev
时,它将把0.0
恢复为NaN
。