Nic*_*ell 6 python pandas pandas-groupby
我有一段 pandas 代码,曾经在 1.0.5 版本中工作。这是我的问题的一个简化的、独立的示例:
import pandas as pd
df = pd.DataFrame(data=[
('bk1', 10),
('bk1', None),
('bk1', 13),
('bk1', None),
('bk2', None),
('bk2', 14),
('bk3', 12),
('bk3', None),
], columns=('book', 'price'))
grouped = df.groupby(['book'], as_index=False, sort=False)
df = grouped.fillna(method='ffill')
print(df)
Run Code Online (Sandbox Code Playgroud)
在此示例中,我们有一个图书销售列表,其中缺少一些价格。我们尝试使用前一行来填充缺失的数据,其中该行是同一本书。
在 Pandas 1.0.5 中,这会生成一个包含两列的数据框:
book price
0 bk1 10.0
1 bk1 10.0
2 bk1 13.0
3 bk1 13.0
4 bk2 NaN
5 bk2 14.0
6 bk3 12.0
7 bk3 12.0
Run Code Online (Sandbox Code Playgroud)
在 Pandas 1.1.0 中,这会删除 book 列,从而导致输出不可用。
price
0 10.0
1 10.0
2 13.0
3 13.0
4 NaN
5 14.0
6 12.0
7 12.0
Run Code Online (Sandbox Code Playgroud)
我已经阅读了1.1.0 版本的补丁说明,但找不到任何有关此更改的注释。
问题:
您可能会问的问题:
为什么不使用 fillna 而不使用 groupby 呢?
在此示例中,带有 bk2 的第一行没有价格,但用前一行(即 bk1 的价格)填充它没有任何意义。
为什么使用填充而不是删除 NA 值?
我的真实代码正在处理时间序列数据,而 ffill 是表达最后已知观察结果的最自然方式。
groupby 可以表示为:
df = grouped.apply(lambda df: df.fillna(method='ffill'))
Run Code Online (Sandbox Code Playgroud)
这在两个版本中都适用。
此问题可能与此更改相关,尽管它发生在不同的版本中:
ffill、bfill和方法之前在返回值中包含了组标签,这pad与其他转换不一致。现在只返回填充的值。(GH21521)backfillDataFrameGroupBygroupby
(来源。)
您可以通过使用更新函数采取不同的方法来解决此问题(与 Nick ODell 提出的解决方案不同):
df.update(df.groupby(['book']).ffill())
print(df)
Out[1]:
book price
0 bk1 10.0
1 bk1 10.0
2 bk1 13.0
3 bk1 13.0
4 bk2 NaN
5 bk2 14.0
6 bk3 12.0
7 bk3 12.0
Run Code Online (Sandbox Code Playgroud)
这也适用于两个版本。