如何向量化标记DataFrame每行最大值为True,替代apply方法?
高效生成每行最大值位置的布尔矩阵(向量化方法)
优化后的向量化实现代码
import pandas as pd a = pd.DataFrame([[2.290119, 5.300725, 17.266693, 75.134857, 0.000000, 0.000000, 0.007606], [0.000000, 7.560276, 55.579175, 36.858266, 0.000000, 0.000000, 0.002284], [0.001574, 15.225538, 39.309742, 45.373800, 0.000951, 0.001198, 0.087197], [0.000000, 55.085390, 15.547927, 29.327661, 0.000000, 0.017691, 0.021331], [0.000000, 66.283488, 15.636673, 17.912315, 0.000000, 0.003185, 0.164339]]) b = a.round(-1) # 十位取整 c = b - a # 向量化方法替代逐行apply round_modifier = c.eq(c.max(axis=1), axis=0) print(round_modifier)
方法说明
- 该方案完全依赖Pandas的向量化运算,避免了
apply的逐行循环逻辑,在数据量较大时性能提升显著。 c.max(axis=1)计算每行的最大值并返回Series,c.eq(..., axis=0)让DataFrame的每个元素与对应行的最大值做比较,直接生成目标布尔矩阵,逻辑和你原代码完全一致——如果一行存在多个相同最大值,所有对应位置都会被标记为True。
利用idxmax生成布尔矩阵的方案
如果你想基于idxmax实现,可通过pd.get_dummies转换,代码如下:
max_cols = c.idxmax(axis=1) round_modifier = pd.get_dummies(max_cols).astype(bool) # 补充原DataFrame中未被选中的列,确保列结构一致 round_modifier = round_modifier.reindex(columns=a.columns, fill_value=False)
注意:此方法仅标记每行第一个出现的最大值位置为True,若一行有多个相同最大值,只会保留第一个,和原apply逻辑有差异,需根据需求选择。
结合你的取整调整场景
针对将取整后总和调整为100的需求,可按以下步骤操作:
- 计算总和偏差:
total_diff = b.sum().sum() - 100 - 若总和为90(偏差-10),在
round_modifier标记的位置(取整变化量最大的位置)将取整结果加10;若总和为110(偏差+10),则将对应位置的取整结果减10。 - 若偏差绝对值大于10,重复上述操作,直至总和为100。
内容的提问来源于stack exchange,提问作者user2009125
相关产品推荐
相关产品推荐

