Pandas groupby 和聚合输出应包括所有原始列(包括未聚合的列)

Posted

技术标签:

【中文标题】Pandas groupby 和聚合输出应包括所有原始列(包括未聚合的列)【英文标题】:Pandas groupby and aggregation output should include all the original columns (including the ones not aggregated on) 【发布时间】:2018-05-01 19:30:09 【问题描述】:

我有以下数据框并且想要:

month 分组记录 每个唯一 UPC_IDQTY_SOLDNET_AMT 总和(每月) 在结果数据框中也包含其余列

我认为我能做到的方法是第一种:创建一个month 列来聚合D_DATES,然后将QTY_SOLDUPC_ID 相加。

脚本:

# Convert date to date time object
df['D_DATE'] = pd.to_datetime(df['D_DATE'])

# Create aggregated months column
df['month'] = df['D_DATE'].apply(dt.date.strftime, args=('%Y.%m',))

# Group by month and sum up quantity sold by UPC_ID
df = df.groupby(['month', 'UPC_ID'])['QTY_SOLD'].sum()

当前数据框:

UPC_ID | UPC_DSC | D_DATE | QTY_SOLD | NET_AMT
----------------------------------------------
111      desc1    2/26/2017   2         10 (2 x $5)
222      desc2    2/26/2017   3         15
333      desc3    2/26/2017   1         4
111      desc1    3/1/2017    1         5
111      desc1    3/3/2017    4         20

期望的输出:

MONTH | UPC_ID | QTY_SOLD | NET_AMT | UPC_DSC
----------------------------------------------
2017-2      111     2         10       etc...
2017-2      222     3         15
2017-2      333     1         4
2017-3      111     5         25

实际输出:

MONTH | UPC_ID  
----------------------------------------------
2017-2      111     2
            222     3
            333     1
2017-3      111     5
...  

问题:

如何为每一行添加月份? 如何包含数据框的其余列? 除了QTY_SOLD之外,还怎么求和NET_AMT

【问题讨论】:

【参考方案1】:

agg 带有 dict 的函数

创建一个dict 的函数并将其传递给agg。您还需要as_index=False 来防止组列成为输出中的索引。

f = 'NET_AMT': 'sum', 'QTY_SOLD': 'sum', 'UPC_DSC': 'first'
df.groupby(['month', 'UPC_ID'], as_index=False).agg(f)

     month  UPC_ID UPC_DSC  NET_AMT  QTY_SOLD
0  2017.02     111   desc1       10         2
1  2017.02     222   desc2       15         3
2  2017.02     333   desc3        4         1
3  2017.03     111   desc1       25         5

毯子sum

只需调用sum,不带任何列名。这处理数字列。对于UPC_DSC,需要单独处理。

g = df.groupby(['month', 'UPC_ID'])
i = g.sum()
j = g[['UPC_DSC']].first()

pd.concat([i, j], 1).reset_index()

     month  UPC_ID  QTY_SOLD  NET_AMT UPC_DSC
0  2017.02     111         2       10   desc1
1  2017.02     222         3       15   desc2
2  2017.02     333         1        4   desc3
3  2017.03     111         5       25   desc1

【讨论】:

【参考方案2】:

我考虑了这么久,感谢您的问题推动我做到这一点。通过使用aggif...else

df.groupby(['month', 'UPC_ID'],as_index=False).agg(lambda x : x.sum() if x.dtype=='int64' else x.head(1))
Out[1221]: 
   month  UPC_ID UPC_DSC     D_DATE  QTY_SOLD  NET_AMT
0      2     111   desc1 2017-02-26         2       10
1      2     222   desc2 2017-02-26         3       15
2      2     333   desc3 2017-02-26         1        4
3      3     111   desc1 2017-03-01         5       25

【讨论】:

以上是关于Pandas groupby 和聚合输出应包括所有原始列(包括未聚合的列)的主要内容,如果未能解决你的问题,请参考以下文章

数据分析—Pandas 中的分组聚合Groupby 高阶操作

Pandas groupby 在保留多个聚合的组内排序

在pandas中使用groupby和聚合的最佳方法

pandas使用groupby函数进行分组聚合并使用agg函数将每个分组特定变量对应的多个内容组合到一起输出(merging content within a specific column of g

Pandas groupby 聚合以截断最早日期而不是最旧日期

pandas使用groupby函数基于指定分组变量对dataframe数据进行分组使用mean函数计算每个分组中的所有数值变量的聚合平均值