首页 > 解决方案 > pandas.groupby 使用具有分类类型与对象的 lambda aggfunc 对相同数据做出不同反应

问题描述

我遇到了一些奇怪的行为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'],合并在这两种情况下都能正常工作。

这是一个大问题 - 这是熊猫中的错误还是我错过了其他东西?

版本:

标签: pythonpandascategorical-data

解决方案


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

添加observed=Truegroupby解决我的问题。

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))))
    )
)

推荐阅读