如何使用groupby结合关联列生成新列及计算水果采购成本均值与次数
解决方案:水果采购数据统计与groupby进阶用法
Hey there! 作为一个采购了多种水果的商贩,我完全懂你需要清晰的采购数据来算账。咱们一步步来解决你的问题,用pandas把这些数据理得明明白白:
1. 先创建你的DataFrame
首先咱们把给定的数据转换成pandas DataFrame,代码如下:
import pandas as pd data = { 'fruit':['apple', 'apple', 'banana', 'cherry', 'apple', 'banana'], 'unit_price':[10, 11.5, 5, 20, 12, 4.5], 'amount':[100, 200, 50, 300, 180, 90] } df = pd.DataFrame(data)
运行后你的DataFrame长这样:
| amount | fruit | unit_price | |
|---|---|---|---|
| 0 | 100 | apple | 10.0 |
| 1 | 200 | apple | 11.5 |
| 2 | 50 | banana | 5.0 |
| 3 | 300 | cherry | 20.0 |
| 4 | 180 | apple | 12.0 |
| 5 | 90 | banana | 4.5 |
2. 计算每种水果的采购次数与平均采购成本
这里要注意:平均采购成本应该是加权平均(因为每次采购的数量不同,买得多的批次对整体成本影响更大),而不是直接取单价的平均值。
2.1 采购次数(即采购批次数量)
一行代码就能搞定,统计每种水果的采购次数:
purchase_counts = df.groupby('fruit').size()
输出结果:
fruit apple 3 banana 2 cherry 1 dtype: int64
2.2 加权平均采购成本
计算逻辑是:总采购成本 ÷ 总采购数量,其中总采购成本是每批次unit_price × amount的总和。咱们可以一次性把采购次数和平均成本算出来:
fruit_stats = df.groupby('fruit').agg( 采购次数=('fruit', 'size'), 加权平均采购成本=('unit_price', lambda x: (x * df.loc[x.index, 'amount']).sum() / df.loc[x.index, 'amount'].sum()) )
运行后得到的统计结果:
| fruit | 采购次数 | 加权平均采购成本 |
|---|---|---|
| apple | 3 | 11.0 |
| banana | 2 | 4.6875 |
| cherry | 1 | 20.0 |
举个例子:苹果的加权平均成本是(10×100 + 11.5×200 + 12×180) ÷ (100+200+180) = 5280 ÷ 480 = 11,这个结果比直接取单价平均值((10+11.5+12)/3≈11.17)更贴合实际采购成本。
3. 使用groupby结合关联列生成新列
如果你想把这些统计数据添加到原DataFrame的每一行(比如每一行都显示该水果的总采购量、平均成本),有两种常用方法:
方法1:用transform直接在原DataFrame添加列
transform会把聚合后的结果广播到原DataFrame的对应行,非常方便:
# 添加每种水果的总采购量 df['总采购量'] = df.groupby('fruit')['amount'].transform('sum') # 添加每种水果的总采购成本 df['总采购成本'] = df.groupby('fruit').apply(lambda x: x['unit_price'] * x['amount']).transform('sum') # 添加每种水果的加权平均采购成本 df['平均采购成本'] = df.groupby('fruit').apply(lambda x: (x['unit_price']*x['amount']).sum()/x['amount'].sum()).transform('first')
处理后的DataFrame会变成这样:
| amount | fruit | unit_price | 总采购量 | 总采购成本 | 平均采购成本 | |
|---|---|---|---|---|---|---|
| 0 | 100 | apple | 10.0 | 480 | 5280 | 11.0 |
| 1 | 200 | apple | 11.5 | 480 | 5280 | 11.0 |
| 2 | 50 | banana | 5.0 | 140 | 655 | 4.6875 |
| 3 | 300 | cherry | 20.0 | 300 | 6000 | 20.0 |
| 4 | 180 | apple | 12.0 | 480 | 5280 | 11.0 |
| 5 | 90 | banana | 4.5 | 140 | 655 | 4.6875 |
方法2:用merge合并聚合结果到原DataFrame
先单独计算统计指标,再通过fruit列关联合并到原DataFrame,这种方式更灵活,适合需要多个统计指标的场景:
# 先计算每种水果的所有统计指标 fruit_summary = df.groupby('fruit').agg( 采购次数=('fruit', 'size'), 总采购量=('amount', 'sum'), 总采购成本=('unit_price', lambda x: (x * df.loc[x.index, 'amount']).sum()), 平均采购成本=('unit_price', lambda x: (x * df.loc[x.index, 'amount']).sum() / df.loc[x.index, 'amount'].sum()) ).reset_index() # 合并到原DataFrame df_with_summary = df.merge(fruit_summary, on='fruit')
最终的df_with_summary和方法1的结果一致,但这种方式可以先单独查看统计摘要,再选择是否合并。
内容的提问来源于stack exchange,提问作者lan
相关产品推荐
相关产品推荐

