pandas.groupby 使用分类类型与对象的 lambda aggfunc 对相同数据的反应不同

pandas.groupby reacting differently on same data using lambda aggfunc with categorical type vs. object

我遇到了 pandas.groupby 的一些奇怪行为。根据我的数据列的 dtype,我得到两个完全不同的结果。一个符合预期,第二个好像很奇怪。

数据集:

country id      plan   consolidation_key
AT01    1000    100    A
AT01    1000    200    B
AT01    2000    300    J
AT01    2000    200    K

在 Excel 文件中。

import numpy as np

def consolidate(d):
    columns=['country', 'id', 'consolidation_key']
#    columns=['id', 'consolidation_key']
    return d.groupby(by=columns).agg(
        plans=pd.NamedAgg(
            column="plan", aggfunc=lambda s: "-".join(sorted(set(s.astype(str))))
        )
    )

d = pd.read_excel(r"path\to\file\test_data.xlsx", sheet_name='data')

data = d
df = consolidate(data)
print(df)
print("-----------")
print("dtypes:")
print(data.dtypes)
print("--------------------")

data2 = d.assign(country=lambda x: pd.Categorical(x["country"]))
df2 = consolidate(data2)
print(df2)
print("-----------")
print("dtypes:")
print(data2.dtypes)

整合中的 lambda 函数没有充分发挥示例数据的作用。它创建了一个独特项目列表 (100-200)。

这给出的结果是

                               plans
country id   consolidation_key      
AT01    1000 A                   100
             B                   200
        2000 J                   300
             K                   200
-----------
dtypes:
country              object
id                    int64
plan                  int64
consolidation_key    object
dtype: object
--------------------
                               plans
country id   consolidation_key      
AT01    1000 A                   100
             B                   200
             J                   NaN
             K                   NaN
        2000 A                   NaN
             B                   NaN
             J                   300
             K                   200
-----------
dtypes:
country              category
id                      int64
plan                    int64
consolidation_key      object
dtype: object

第一次合并到 df 看起来不错。 df2 中的第二个包含具有 NaN 值的额外项目。它看起来像是两个 ID 的交叉连接。 有趣的是,这仅在 columns=['country', 'id', 'consolidation_key'] 时发生。使用 columns=['id', 'consolidation_key'],合并在两种情况下都能正常工作。

这是一个大问题 - 这是 pandas 中的错误还是我遗漏了什么?

版本:

阅读@jezrael 的回答中的帖子,我在 https://github.com/pandas-dev/pandas/issues/17594#issuecomment-545238294 找到了一条重要评论。

observed=True 添加到 groupby 解决了我的问题。

def consolidate(d):
columns=['country', 'id', 'consolidation_key']
return d.groupby(by=columns, observed=True).agg(
    plans=pd.NamedAgg(
        column="plan", aggfunc=lambda s: "-".join(sorted(set(s.astype(str))))
    )
)