如何在Pandas DataFrame中按分组计算Count的同比(YoY)变化率?
解决方案
嘿,这问题我熟!咱们一步步来搞定这个2018年相对2017年的百分比变化计算,保证你能直接复用代码~
第一步:先构建示例DataFrame
首先咱们把你给的示例数据转换成Pandas DataFrame,这样你可以直接运行验证:
import pandas as pd # 你的示例数据 data_rows = [ [131, 1, 'dir', 'mob', 2017], [244, 1, 'dir', 'mob', 2018], [311, 1, 'org', 'mob', 2017], [332, 1, 'org', 'mob', 2018], [212, 2, 'dir', 'dsk', 2017], [311, 2, 'dir', 'dsk', 2018], [401, 2, 'org', 'mob', 2017], [283, 2, 'org', 'mob', 2018] ] # 创建DataFrame并指定列名 df = pd.DataFrame(data_rows, columns=['count', 'w', 'c', 'd', 'y'])
第二步:计算分组后的百分比变化
这里给你两种常用方法,按需选择:
方法一:用pivot_table快速转置年份(最简洁)
这种方法把年份转成列,直观又好计算,适合你这种只有两年数据的场景:
# 按w、c、d分组,把年份转成列,值为count pivot_df = df.pivot_table( index=['w', 'c', 'd'], columns='y', values='count' ).reset_index() # 计算百分比变化:((2018值 - 2017值)/2017值)*100 pivot_df['pct_change_2018_vs_2017'] = ((pivot_df[2018] - pivot_df[2017]) / pivot_df[2017]) * 100 # 如果你担心有些分组缺年份数据,可以过滤掉含NaN的行 pivot_df = pivot_df.dropna(subset=[2017, 2018])
运行后你会得到这样的结果:
| w | c | d | 2017 | 2018 | pct_change_2018_vs_2017 |
|---|---|---|---|---|---|
| 1 | dir | mob | 131 | 244 | 86.259542 |
| 1 | org | mob | 311 | 332 | 6.752412 |
| 2 | dir | dsk | 212 | 311 | 46.698113 |
| 2 | org | mob | 401 | 283 | -29.426434 |
方法二:用groupby结合自定义逻辑(更灵活)
如果以后你的数据有更多年份,或者需要更复杂的分组逻辑,这种方法扩展性更强:
# 先按分组和年份排序,确保每个分组内年份是有序的 df_sorted = df.sort_values(by=['w', 'c', 'd', 'y']) # 分组后计算每个组的两年数据和变化率 result_df = df_sorted.groupby(['w', 'c', 'd']).apply( lambda group: pd.Series({ '2017_count': group[group['y'] == 2017]['count'].iloc[0], '2018_count': group[group['y'] == 2018]['count'].iloc[0], 'pct_change': ((group[group['y'] == 2018]['count'].iloc[0] - group[group['y'] == 2017]['count'].iloc[0]) / group[group['y'] == 2017]['count'].iloc[0]) * 100 }) ).reset_index()
这个方法和上面的结果完全一致,只是实现方式更灵活。
内容的提问来源于stack exchange,提问作者Mark Ginsburg
相关产品推荐
相关产品推荐

