如何为Pandas DataFrame计算行占比并生成降序带列名描述列
问题描述
原始DataFrame代码如下:
import pandas as pd data1 = [['A', 10, 30, 15, 45], ['B', 22, 35, 25, 18], ['C', 40, 27, 28, 5]] df1 = pd.DataFrame(data1, columns= ['Units', 'Normal', 'Bad', 'Good', 'Neutral'])
需求:
为df1新增一列Proportion by largest to smallest,实现以下效果:
- 计算每行中
Normal、Bad、Good、Neutral列的数值占该行总和的比例 - 将这些比例按从高到低排序
- 保留对应列名,格式为
列名 = 比例值%,多个结果用逗号分隔
目标效果示例:
data2 = [['A', 10, 30, 15, 45, 'Neutral = 0.45%, Bad = 0.3%, Good = 0.15%, Normal = 0.10%'], ['B', 22, 35, 25, 18, 'Bad = 0.35%, Good = 0.25%, Normal = 0.22%, Neutral = 0.18%'], ['C', 40, 27, 28, 5, 'Normal = 0.4%, Good = 0.28%, Bad = 0.27%, Neutral = 0.05%']] df2 = pd.DataFrame(data2, columns= ['Units', 'Normal', 'Bad', 'Good', 'Neutral', 'Proportion by largest to smallest'])
解决方案
通过自定义函数结合apply方法实现自动化处理,适配大规模数据集:
import pandas as pd # 定义单行处理函数 def format_proportions(row): # 提取数值列,排除非数值的Units列 numeric_vals = row.drop('Units') # 计算该行数值总和 total = numeric_vals.sum() # 计算每个数值占总和的比例 proportions = numeric_vals / total # 按比例降序排序 sorted_props = proportions.sort_values(ascending=False) # 格式化每个条目,自动去除小数末尾多余的0 formatted_items = [] for col, val in sorted_props.items(): formatted_val = "{:.2f}".format(val).rstrip('0').rstrip('.') formatted_items.append(f"{col} = {formatted_val}%") # 拼接成最终字符串 return ', '.join(formatted_items) # 应用函数到每行,生成目标列 df1['Proportion by largest to smallest'] = df1.apply(format_proportions, axis=1) # 查看结果 print(df1)
代码说明
format_proportions函数负责单行数据处理:- 筛选出该行的数值列,排除
Units列 - 计算该行所有数值的总和
- 计算每个数值占总和的比例
- 按比例从高到低排序
- 将列名与对应比例格式化为指定字符串,最后拼接成完整文本
- 筛选出该行的数值列,排除
apply(axis=1)将函数批量应用到每一行,自动生成目标列,无需手动处理每行数据
内容的提问来源于stack exchange,提问作者Oshimiri Atata
相关产品推荐
相关产品推荐

