熊猫按分组依据求和,但排除某些列


88

在Pandas数据框上进行分组的最佳方法是什么,但要从该分组中排除一些列呢?例如我有以下数据框:

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

我想对“国家”和“项目代码”列进行分组,仅计算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()操作中的列和要排除的列?

Answers:


117

您可以选择分组依据的列:

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
如何在每个国家/地区和商品代码的记录计数中添加另一列?
Sushant Kulkarni

您可以在仅包含1的分组之前创建一个虚拟列,然后将这些总和加起来以创建一个计数。
马特W.18年

如果您只想排除一两列,则获得所有列名,listColumns = list(df.columns)然后删除不想要的列,listColumns.remove('Y1964')最后进行求和:df.groupby(['Country', 'Item_Code'])[listColumns].sum()
Roberto Stelling

非常感谢。我可以让groupby工作,但不能让选择部分工作。我放入的列列表在数据框中,但它会不断引发ValueError:cannot reindex from a duplicate axis
Bowen Liu

@BowenLiu如果您有多个具有相同名称的列,则会显示此错误。在这种情况下,您将必须使用iloc to或loc来获取所需的列,我认为您必须在groupby之前执行此操作。
安迪·海登

40

agg功能将为您完成此任务。传递列,并作为带有列的字典,输出:

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”的agg函数。

为了准确地获得您希望看到的内容,请将其他列包括在group by中,并将总和应用于框架中的Y变量:

df.groupby(['Code', 'Country', 'Item_Code', 'Item', 'Ele_Code', 'Unit']).agg({'Y1961': np.sum, 'Y1962': np.sum, 'Y1963': np.sum})

1
谢谢,可以概括一下吗?我有许多Y1961形式的列...所以我生成了一个像这样的列表:yrs = ['Y'+ str(x)表示x在范围内(1961,2010 + 1,1)]。您的解决方案可以在agg中使用“ yrs”吗?
user308827 2015年

我真的喜欢这个主意。诀窍是使用numpy sum函数构造此dict。相反,如果您只想对所有剩余的列求和,那么如果group by语句中包含所有group by列,则您的原始解决方案将起作用。
leroyJr 2015年

11

如果您正在寻找一种适用于许多列的更通用的方法,则可以建立一个列名列表并将其作为分组数据框的索引传递。以您的情况为例:

columns = ['Y'+str(i) for year in range(1967, 2011)]

df.groupby('Country')[columns].agg('sum')
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.