如何无循环实现Pandas中分组指定行的col3值对比分析
问题描述
现有如下结构的DataFrame:
df col1 col2 col3 0 1 "A" 10 1 1 "B" 20 2 1 "C" 30 ... k "A" 15 n+1 k "B" 10 n+2 k "C" 5
需求:针对col1值相同的行,分别计算col2为"A"与"B"、"A"与"C"的col3值比例,公式为(A的col3 / 对应组的B/C的col3) * 100,生成如下结构的结果DataFrame:
da_df col2 ratio 0 "AvsB" 33.3 # 10/30*100 1 "AvsC" 50.0 # 10/20*100 ... 2k "AvsB" 150 # 15/10*100 2k+1 "AvsC" 300 # 15/5*100
无循环解决方案
使用Pandas的透视表和数据重塑功能实现,全程基于向量化操作,无需for循环:
- 透视数据:将
col2的不同取值转为列,让每个col1分组对应一行,包含A、B、C的col3值 - 计算比例:基于透视后的列直接计算AvsB和AvsC的比例
- 重塑为长格式:将宽表转为目标要求的长表结构
代码实现:
import pandas as pd # 示例数据(替换为实际数据即可) data = { 'col1': [1, 1, 1, 2, 2, 2], 'col2': ['A', 'B', 'C', 'A', 'B', 'C'], 'col3': [10, 20, 30, 15, 10, 5] } df = pd.DataFrame(data) # 1. 生成透视表,将col2的取值转为列 pivot_df = df.pivot(index='col1', columns='col2', values='col3').reset_index() # 2. 计算两个比例项 pivot_df['AvsB'] = (pivot_df['A'] / pivot_df['B']) * 100 pivot_df['AvsC'] = (pivot_df['A'] / pivot_df['C']) * 100 # 3. 转换为目标长格式结构 da_df = pivot_df.melt( id_vars=['col1'], value_vars=['AvsB', 'AvsC'], var_name='col2', value_name='ratio' ).drop(columns='col1') # 移除原col1,匹配目标结构 # 可选:按需求保留小数位数 da_df['ratio'] = da_df['ratio'].round(1) print(da_df)
执行后输出结果:
col2 ratio 0 AvsB 50.0 1 AvsB 150.0 2 AvsC 33.3 3 AvsC 300.0
(注:若需要调整行的顺序,可对da_df按col2排序,或在melt的value_vars中指定顺序)
内容的提问来源于stack exchange,提问作者PresentEco
相关产品推荐
相关产品推荐

