使用df.iloc[:, 0]分组聚合时为何会拼接分组列的字符串值?
df.iloc[:, 0]分组聚合时为何会拼接分组列的字符串值?
这个问题其实是因为两种分组方式在pandas里的底层逻辑完全不一样,我给你拆解清楚:
1. 第一种方式:df.groupby(df.columns[0], as_index=False).sum()的逻辑
df.columns[0]其实就是字符串'species',相当于你直接用列名指定分组键。当pandas看到你用列名字符串分组时,它会自动把该列当作分组的依据,并且在执行聚合操作(比如sum)时,默认不会对分组键本身应用聚合函数——它只会保留每个分组对应的唯一键值,然后对其他数值列求和,这就是你得到正常结果的原因。
2. 第二种方式:df.groupby(df.iloc[:, 0], as_index=False).sum()的逻辑
df.iloc[:,0]返回的是整个species列的Series对象,这时候你是把这个Series当作分组的"依据"传入,但原DataFrame里的species列依然是待聚合的列之一!
而在pandas里,字符串类型的Series调用sum()方法,行为就是把所有字符串拼接在一起——比如你有6个'a',sum之后就是'aaaaaa',这就是你看到分组列被重复拼接的核心原因。你可以自己验证一下:
df[df['species'] == 'a']['species'].sum()
运行这段代码,结果就是'aaaaaa',和你第二种方式得到的结果完全一致。
怎么用iloc的方式得到正确结果?
如果你想通过位置指定分组列,又不想让分组列被聚合,可以这么做:
# 拿到分组列的列名,再用列名分组 grouped_df2 = df.groupby(df.iloc[:,0].name, as_index=False).sum() # 或者手动指定要聚合的列 grouped_df2 = df.groupby(df.iloc[:,0], as_index=False)[['s1','s2','s3','s4']].sum()
这样就能得到和第一种方式一样的正常结果啦。
备注:内容来源于stack exchange,提问作者Ray
相关产品推荐
相关产品推荐

