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 中的错误还是我遗漏了什么?
版本:
- Python 3.7.3
- IPython 7.8.0
- Pandas 0.25.1(和 0.25.2)
阅读@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))))
)
)
我遇到了 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 中的错误还是我遗漏了什么?
版本:
- Python 3.7.3
- IPython 7.8.0
- Pandas 0.25.1(和 0.25.2)
阅读@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))))
)
)