我想对 pandas 数据框进行分组和聚合。 我有一个自定义聚合函数,应该根据它所应用的系列的数据类型来执行不同的操作。 然而,有些柱子却悄无声息地消失了。它似乎与 dtype 条件有关。
在制作可重现示例的过程中,我注意到一些奇怪的事情:
- 如果我首先测试该系列是否为 dtype
string
,然后对其他情况使用else
语句,我的数字列将被悄悄删除 - 但是,如果我首先测试
series.dtype == "int64"
,它会按预期工作。
这是我的可重现示例:
import pandas as pd
# reprex dataframe
groups = ["group1", "group1", "group2", "group2"]
numbers = [1, 2, 3, 4]
letters = ["a", "b", "c", "c"]
data = {"group": groups, "number": numbers, "letter": letters}
df = pd.DataFrame(data)
df["letter"] = df["letter"].astype("string")
# custom aggregation functions
def is_int(series):
if series.dtype == "int64":
return "int64"
else:
return "not an int"
def is_string(series):
if series.dtype == "string":
return "string"
else:
return "not a string"
# the confusing part
df.groupby("group").agg(is_int) # works as expected
df.groupby("group").agg(is_string) # the "number" column disappears silently
欢迎任何关于为什么会发生这种情况以及如何处理它的见解!
最佳答案
new Dtypes都是实验性的,因此总是有奇怪的怪癖。问题是,虽然字符串数据类型与 'string'
的比较有意义,但对于任何其他数据类型来说都失败。
df['letter'].dtype == 'string'
# True
df['number'].dtype == 'string'
#TypeError: data type 'string' not understood
因此,groupby 会默默地忽略第二种情况下的错误,并且不会显示输出,因为它无法聚合该列。正确的比较是与实际字符串Dtype:pd.StringDtype
,并使用isinstance
def is_string(series):
if isinstance(series.dtype, pd.StringDtype):
return "string"
else:
return "not a string"
df.groupby("group").agg(is_string)
# number letter
#group
#group1 not a string string
#group2 not a string string
关于pandas agg 具有自定义聚合函数和 dtype 条件 : column disappears silently,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66922659/