Pandas基于指定列重基化值:计算相对百分比变化并添加均值行
解决方案:计算相对基准列的百分比变化并添加均值行
没问题,我来帮你搞定这个需求!针对你这种50行50列的大型DataFrame,需要计算所有列相对指定基准列的百分比变化,还要在底部添加均值行的场景,这里有个通用的实现方案,完全适配你的需求:
步骤说明
- 分离数据列:先把非数值列(比如你的
Name列)和日期数值列分开,避免对文本列做计算。 - 指定基准列:你提到基准列是第14列,注意Python是0索引,所以如果是整个DataFrame的第14列,索引是
13;如果是数值列里的第14列,索引也是13。当然你也可以直接用列名指定,更稳妥。 - 计算百分比变化:用每列的值减去基准列的值,再除以基准列的值,最后乘以100得到变化百分比。
- 格式化显示:把计算结果转换成带
%的字符串,让表格更直观。 - 添加均值行:计算每列的百分比变化均值,追加到DataFrame底部。
完整代码示例
import pandas as pd # 假设你的原始DataFrame名为df,先按你的示例构造一个小测试用例(实际替换成你的真实数据) data = { 'Name': ['ABC', 'DEF', 'GHI'], '2018-02-28': [110, 120, 130], '2018-01-31': [109, 119, 129], '2018-12-31': [108, 118, 128], '2017-11-30': [100, 100, 100], '2017-10-31': [95, 85, 75], '2017-09-30': [90, 80, 70] } df = pd.DataFrame(data, index=[11,22,33]) df.index.name = 'ID' # -------------------------- 核心处理逻辑 -------------------------- # 1. 分离非数值列和数值列 non_numeric_cols = ['Name'] numeric_cols = [col for col in df.columns if col not in non_numeric_cols] # 2. 指定基准列:这里用列名更稳妥,或者用索引(比如base_col = numeric_cols[13] 对应第14个数值列) base_col = '2017-11-30' # 替换成你实际的基准列名,或者用索引方式 # 3. 计算百分比变化:(当前列值 - 基准列值) / 基准列值 * 100 pct_change = df[numeric_cols].sub(df[base_col], axis=0).div(df[base_col], axis=0) * 100 # 4. 合并非数值列,恢复原始结构 result = pd.concat([df[non_numeric_cols], pct_change], axis=1) # 5. 格式化数值为百分比字符串(保留1位小数,可根据需求调整) result[numeric_cols] = result[numeric_cols].applymap(lambda x: f"{x:.1f}%" if pd.notna(x) else "") # 6. 计算并添加均值行 avg_values = pct_change.mean().tolist() avg_row = pd.Series(['Average'] + avg_values, index=result.columns) # 格式化均值为百分比 avg_row[numeric_cols] = avg_row[numeric_cols].apply(lambda x: f"{x:.1f}%") # 把均值行追加到底部,保留原ID索引逻辑(这里给均值行设置索引为'Average') final_result = pd.concat([result, avg_row.to_frame().T], axis=0) final_result.index = final_result.index.astype(str) # 统一索引类型,避免混合 final_result.index[-1] = 'Average' # 给最后一行设置索引名 # 输出结果 print(final_result)
关键注意事项
- 基准列的选择:如果不确定列索引,直接用列名指定
base_col会更可靠,避免因为列顺序变化出错。 - 处理异常值:如果基准列存在0值,会触发除以0的错误,建议提前用
df[base_col] = df[base_col].replace(0, pd.NA)处理,或者过滤掉对应行。 - 索引兼容:如果你的原始DataFrame用
ID作为索引,代码里最后给均值行设置索引为Average,保证表格结构统一。
内容的提问来源于stack exchange,提问作者Singapore 123
相关产品推荐
相关产品推荐

