如何在Pandas DataFrame中按事件分组统计Profile占比并计算Indy均值
Pandas分组统计实现方案
步骤说明
- 拆分多字母Profile:将Profile列中包含多个字母(如"AB")的内容拆分为单个字符,展开成多行,同时过滤掉NaN值和非A-D的字符。
- 统计字母占比:按EventName分组统计各字母的出现次数,计算占比并格式化为指定的字符串形式。
- 计算Indy均值:按EventName分组计算Indy列的均值,保留两位小数。
- 合并结果并排序:将上述两个结果合并,按EventName排序后输出。
完整代码
import pandas as pd # 初始化示例数据(实际使用时替换为你的数据源) data = { 'Date': ['2010-11-19', '2010-11-23', '2010-11-24', '2010-11-30', '2010-12-01'], 'PtsMoved': [16.250, 43.000, 50.500, 34.870, 54.500], 'Profile': ['A', pd.NA, 'D', pd.NA, 'B'], 'Type': ['High Impact Expected']*5, 'EventName': ['Fed Chairman Bernanke Speaks', 'Prelim GDP q/q', 'New Home Sales', 'CB Consumer Confidence', 'ISM Manufacturing PMI'], 'Indy': [29.2500, 29.5500, 35.2000, 31.5240, 32.3740] } df = pd.DataFrame(data) # 拆分Profile中的多字母并展开为单行单字母 profile_exploded = df.dropna(subset=['Profile']).assign( Profile=lambda x: x['Profile'].str.split('') ).explode('Profile').query('Profile in ["A","B","C","D"]') # 统计各EventName下的字母频次,计算占比并格式化字符串 profile_counts = profile_exploded.groupby(['EventName', 'Profile']).size().unstack(fill_value=0) total_counts = profile_counts.sum(axis=1) profile_ratios = (profile_counts.div(total_counts, axis=0) * 100).round(0).astype(int) profile_str = profile_ratios.apply( lambda row: ', '.join([f'{k}({v}%)' for k, v in row.items() if v > 0]), axis=1 ) # 计算Indy列的均值,保留两位小数 indy_mean = df.groupby('EventName')['Indy'].mean().round(2) # 合并结果并按EventName排序 result = pd.concat([indy_mean, profile_str], axis=1).rename(columns={0: 'Profile'}).sort_index() # 输出最终结果 print(result)
示例输出
| EventName | Indy | Profile |
|---|---|---|
| CB Consumer Confidence | 31.52 | |
| Fed Chairman Bernanke Speaks | 29.25 | A(100%) |
| ISM Manufacturing PMI | 32.37 | B(100%) |
| New Home Sales | 35.2 | D(100%) |
| Prelim GDP q/q | 29.55 |
内容的提问来源于stack exchange,提问作者ningray
相关产品推荐
相关产品推荐

