Pandas groupby 在 1.1.0 中 fillna 之后删除组列

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 版本的补丁说明,但找不到任何有关此更改的注释。

问题:

  1. 这是 Pandas 中的错误,还是我依赖​​于未定义的行为?
  2. 有没有更自然的方式来表达这一点?

您可能会问的问题:

  1. 为什么不使用 fillna 而不使用 groupby 呢?

    在此示例中,带有 bk2 的第一行没有价格,但用前一行(即 bk1 的价格)填充它没有任何意义。

  2. 为什么使用填充而不是删除 NA 值?

    我的真实代码正在处理时间序列数据,而 ffill 是表达最后已知观察结果的最自然方式。

Nic*_*ell 8

解决方法

groupby 可以表示为:

df = grouped.apply(lambda df: df.fillna(method='ffill'))
Run Code Online (Sandbox Code Playgroud)

这在两个版本中都适用。

原因

此问题可能与此更改相关,尽管它发生在不同的版本中:

ffillbfill和方法之前在返回值中包含了组标签,这pad与其他转换不一致。现在只返回填充的值。(GH21521)backfillDataFrameGroupBygroupby

来源。)


Gui*_*cia 5

您可以通过使用更新函数采取不同的方法来解决此问题(与 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)

这也适用于两个版本。