蟒熊猫:替换GROUPBY操作

时间:2019-01-30 18:44:46

标签: python pandas

我有一个pandas dataframe下表:

| ID | Name | Sales | Source   |
|----|------|-------|----------|
| 1  | a    | 34    | Source A |
| 2  | b    | 3423  | Source A |
| 3  | c    | 2     | Source A |
| 4  | d    | 342   | Source A |
| 3  | c    | 34    | Source A |
| 5  | e    | 234   | Source A |
| 6  | f    | 234   | Source A |
| 7  | g    | 23    | Source A |
| 1  | a    | 12    | Source B |
| 2  | b    | 42    | Source B |
| 3  | c    | 9     | Source B |
| 2  | b    | 22    | Source B |
| 1  | a    | 1     | Source B |
| 8  | h    | 56    | Source B |

最好的方法是(i)汇总每个ID的每个ID的销售额,以及(ii)将结果放入两个新列“来源A”和“来源B”,以使结果dataframe看起来如下:

| ID | Name | Source A | Source B |
|----|------|----------|----------|
| 1  | a    | 34       | 13       |
| 2  | b    | 3423     | 64       |
| 3  | c    | 36       | 9        |
| 4  | d    | 342      | 0        |
| 5  | e    | 234      | 0        |
| 6  | f    | 234      | 0        |
| 7  | g    | 23       | 0        |
| 8  | h    | 0        | 56       |

我的初始方法被如下:

data = {"ID":[1,2,3,4,3,5,6,7,1,2,3,2,1,8], 
      "Name":list("abcdcefgabcbah"), 
      "Sales":[34,3423,2,342,34,234,234,23,12,42,9,22,1,56],
      "Source":["Source A"]*8 + ["Source B"]*6
     }
df = pd.DataFrame(data)

df.groupby(["ID","Name","Source"])["Sales"].sum().unstack()

问题:我的初始表是使用不同的文件而不是应用pd.concat构建的。因此,感觉我可以通过首先以不同的方式串联(或合并)来获得最终表。是否有更好的方法来实现这一目标?作为侧节点:实际数据表由总分6个不同来源

感谢您的帮助!

2 个答案:

答案 0 :(得分:3)

您可以使用pd.crosstab

pd.crosstab(df.Name, df.Source, df.Sales, aggfunc='sum').fillna(0)

输出:

Source  Source A  Source B
Name                      
a           34.0      13.0
b         3423.0      64.0
c           36.0       9.0
d          342.0       0.0
e          234.0       0.0
f          234.0       0.0
g           23.0       0.0
h            0.0      56.0

或者,pivot_table

df.pivot_table('Sales','Name','Source', aggfunc='sum').fillna(0)

输出:

Source  Source A  Source B
Name                      
a           34.0      13.0
b         3423.0      64.0
c           36.0       9.0
d          342.0       0.0
e          234.0       0.0
f          234.0       0.0
g           23.0       0.0
h            0.0      56.0

或将set_indexsumlevel参数一起使用,然后将unstack

df.set_index(['Name','Source'])['Sales'].sum(level=[0,1]).unstack(fill_value=0) 

输出:

Source  Source A  Source B
Name                      
a             34        13
b           3423        64
c             36         9
d            342         0
e            234         0
f            234         0
g             23         0
h              0        56

答案 1 :(得分:1)

尝试以下代码:

df.groupby(['Name', 'Source'])['Sales'].sum()\
    .unstack(1).fillna(0).reset_index()