Pandas:大DataFrame按行转换为百分比的高效最优方法
大型DataFrame按行转百分比的高效实现优化
我们的目标是针对存储数值型数据的大型DataFrame,找到将其值按行转换为百分比的最快实现方式,需处理全0行的特殊情况(避免除以0导致的NaN,最终替换为0)。示例如下:
原始数值DataFrame:
a b c 0 1 2 3 1 0 0 0 2 7 8 9转换为按行百分比后的结果:
a b c 0 16.67 33.33 50.0 1 0.00 0.00 0.0 2 29.17 33.33 37.5
当前已实现的高效方案
目前已验证的高效实现代码如下(可复现):
1. 创建示例DataFrame
import pandas as pd import numpy as np # 创建示例DataFrame df = pd.DataFrame( np.array([[1, 2, 3], [0, 0, 0], [7, 8, 9]]), columns=['a', 'b', 'c'] )
2. 定义处理函数
def transform_into_percent_vs_total_per_row(df): return ( df # 创建每行总和列 .assign(total=lambda df: df.sum(axis=1)) # 按行计算百分比 .pipe(lambda x: x.div(x.total, axis=0)*100) # 保留两位小数 .round(2) # 替换全0行产生的NaN为0 .fillna(0) # 删除临时总和列 .drop(columns=["total"]) ) # 调用函数处理 result_df = df.pipe(transform_into_percent_vs_total_per_row)
该方案在1200万行×200列的大型DataFrame上表现高效,远快于df.apply(lambda x: x/sum(x)*100, axis=1).round(2).fillna(0)这类逐行apply的实现。
更优的向量化实现(基于Numpy)
利用Numpy的向量化运算可进一步提升性能,避免pandas中间步骤的额外开销,直接操作底层数组:
def transform_percent_numpy(df): # 转换为numpy数组 arr = df.values # 计算每行总和,reshape为列向量以便广播运算 row_sums = arr.sum(axis=1).reshape(-1, 1) # 计算百分比:直接处理除以0的情况,避免生成NaN percent_arr = np.where(row_sums == 0, 0, (arr / row_sums) * 100) # 保留两位小数 percent_arr = np.round(percent_arr, 2) # 转换回DataFrame,保留原列名与索引 return pd.DataFrame(percent_arr, columns=df.columns, index=df.index)
性能优势说明
针对超大型DataFrame(如1200万行×200列),该方案的优势显著:
- 减少了pandas列操作(
assign、drop)带来的额外开销 - 直接在数组层面完成运算,避开pandas API的封装成本
- 处理全0行的逻辑更直接,无需后续
fillna操作
内容的提问来源于stack exchange,提问作者an ch
相关产品推荐
相关产品推荐

