如何用iloc/loc为Pandas DataFrame添加每行最大值及对应列名(替代弃用ix)
用loc/iloc替代弃用的ix实现DataFrame每行最大值对应列名添加
问题背景
之前用已弃用的ix方法实现给DataFrame添加每行最大值及对应列名的功能,改用iloc或loc时触发报错:
IndexError: boolean index did not match indexed array along dimension 0; dimension is 3 but corresponding boolean dimension is 5
样例输入DataFrame:
a b c maxval 0 1 0 0 1 1 0 0 0 0 2 0 1 0 1 3 1 0 0 1 4 3 1 0 3
期望输出:
a b c maxval maxcol 0 1 0 0 1 a 1 0 0 0 0 a,b,c 2 0 1 0 1 b 3 1 0 0 1 a 4 3 1 0 3 a
报错原因
这个错误是因为计算时没有排除maxval列,导致布尔索引的维度(包含4列的整个DataFrame)和目标计算列(仅a、b、c三列)不匹配,引发维度兼容问题。
解决方案
只需针对a、b、c三列计算,避开maxval列即可,提供两种实现方式:
方式1:apply逐行处理
import pandas as pd # 构建样例数据 df = pd.DataFrame({ 'a': [1, 0, 0, 1, 3], 'b': [0, 0, 1, 0, 1], 'c': [0, 0, 0, 0, 0], 'maxval': [1, 0, 1, 1, 3] }) # 指定需要计算的目标列 target_cols = ['a', 'b', 'c'] # 逐行找出等于maxval的列名并拼接 df['maxcol'] = df.apply( lambda row: ','.join([col for col in target_cols if row[col] == row['maxval']]), axis=1 )
方式2:向量化处理(更高效)
import pandas as pd df = pd.DataFrame({ 'a': [1, 0, 0, 1, 3], 'b': [0, 0, 1, 0, 1], 'c': [0, 0, 0, 0, 0], 'maxval': [1, 0, 1, 1, 3] }) target_cols = ['a', 'b', 'c'] # 生成布尔矩阵,标记每行中值等于maxval的位置 bool_matrix = df[target_cols].eq(df['maxval'], axis=0) # 提取每行中布尔值为True的列名并拼接 df['maxcol'] = bool_matrix.apply(lambda x: ','.join(x.index[x]), axis=1)
两种方式运行后都能得到期望输出,核心是通过target_cols明确限定计算范围,避免包含maxval列导致维度不匹配,完美替代原有的ix方法。
内容的提问来源于stack exchange,提问作者vestland
相关产品推荐
相关产品推荐

