Pandas 按 groupby 求和,但不包括某些列
Posted
技术标签:
【中文标题】Pandas 按 groupby 求和,但不包括某些列【英文标题】:Pandas sum by groupby, but exclude certain columns 【发布时间】:2015-12-21 11:01:16 【问题描述】:在 Pandas 数据框上执行 groupby 的最佳方法是什么,但从该 groupby 中排除某些列?例如我有以下数据框:
Code Country Item_Code Item Ele_Code Unit Y1961 Y1962 Y1963
2 Afghanistan 15 Wheat 5312 Ha 10 20 30
2 Afghanistan 25 Maize 5312 Ha 10 20 30
4 Angola 15 Wheat 7312 Ha 30 40 50
4 Angola 25 Maize 7312 Ha 30 40 50
我想按 Country 和 Item_Code 列分组,只计算 Y1961、Y1962 和 Y1963 列下的行的总和。生成的数据框应如下所示:
Code Country Item_Code Item Ele_Code Unit Y1961 Y1962 Y1963
2 Afghanistan 15 C3 5312 Ha 20 40 60
4 Angola 25 C4 7312 Ha 60 80 100
现在我正在这样做:
df.groupby('Country').sum()
但是,这也会将 Item_Code 列中的值相加。有什么方法可以指定 sum()
操作中包含哪些列以及排除哪些列?
【问题讨论】:
【参考方案1】:如果您正在寻找一种更通用的方法来应用到许多列,您可以做的是构建一个列名列表并将其作为分组数据框的索引传递。在你的情况下,例如:
columns = ['Y'+str(i) for year in range(1967, 2011)]
df.groupby('Country')[columns].agg('sum')
【讨论】:
【参考方案2】:您可以选择 groupby 的列:
In [11]: df.groupby(['Country', 'Item_Code'])[["Y1961", "Y1962", "Y1963"]].sum()
Out[11]:
Y1961 Y1962 Y1963
Country Item_Code
Afghanistan 15 10 20 30
25 10 20 30
Angola 15 30 40 50
25 30 40 50
请注意,传递的列表必须是列的子集,否则您将看到 KeyError。
【讨论】:
如何将每个国家和项目代码的记录计数作为另一列包含在内? 您可以在分组之前创建一个虚拟列,该列仅包含 1。然后 sum 会将这些汇总起来创建一个计数。 如果您只想排除一两列,那么您将获得所有列名称,如listColumns = list(df.columns)
然后删除您不想要的列 listColumns.remove('Y1964')
最后进行求和:df.groupby(['Country', 'Item_Code'])[listColumns].sum()
非常感谢。我可以让 groupby 工作,但不能让选择部分工作。我放入的列列表在数据框中,但它不断提高 ValueError:cannot reindex from a duplicate axis
@BowenLiu 如果您有多个具有相同名称的列,则会显示此错误。在这种情况下,您必须使用 iloc to 或 loc 来获取所需的列,我认为您必须在 groupby 之前这样做。【参考方案3】:
agg
函数将为您执行此操作。将列和函数作为带有列的 dict 传递,输出:
df.groupby(['Country', 'Item_Code']).agg('Y1961': np.sum, 'Y1962': [np.sum, np.mean]) # Added example for two output columns from a single input column
这将只显示分组列和指定的聚合列。在这个例子中,我包含了两个应用于“Y1962”的聚合函数。
要准确获得您希望看到的内容,请将其他列包含在 group by 中,并将总和应用于框架中的 Y 变量:
df.groupby(['Code', 'Country', 'Item_Code', 'Item', 'Ele_Code', 'Unit']).agg('Y1961': np.sum, 'Y1962': np.sum, 'Y1963': np.sum)
【讨论】:
谢谢,这可以概括吗?我有很多 Y1961 形式的列...所以我生成了一个这样的列表:yrs = ['Y' + str(x) for x in range(1961, 2010 + 1, 1)]。您的解决方案可以在 agg 中使用“yrs”吗? 我真的很喜欢这个主意。诀窍是构造这个dict,其值为numpy sum 函数。相反,如果您只想对所有剩余的列求和,那么如果所有 group by 列都包含在 group by 语句中,那么您的原始解决方案将起作用。以上是关于Pandas 按 groupby 求和,但不包括某些列的主要内容,如果未能解决你的问题,请参考以下文章
Pandas DataFrame groupby,跨列计数和求和
数据分析—Pandas 中的分组聚合Groupby 高阶操作