如何高效为多级列DataFrame批量添加条件列(无需循环)
多级列DataFrame批量新增分组列的高效实现
我有一个带多级列(MultiIndex)的DataFrame,需要基于同分组内其他列的条件,为所有level_1分组(分组动态可变,可新增或删除)统一添加level_2列e_1。
示例DataFrame构建代码
import pandas as pd import numpy as np level_1 = ['A1', 'A1', 'A1', 'B1', 'B1', 'B1', 'C1', 'C1', 'C1'] level_2 = ['a_1', 'b_1', 'c_1', 'a_1', 'b_1', 'c_1', 'a_1', 'b_1', 'c_1'] data = [['a', 23, 'h', 'o', 45, 'v', 'a3', 1, 'b1'], ['b', 34, 'i', 'p', 3, 'w', 'a4', 32, 'b2'], ['c', 5, 'j', 'q', 7, 'x', 'a5', 6, 'b3'], ['d', 2, 'k', 'r', 5, 'y', 'a6', 76, 'b4'], ['e', 78, 'l', 's', 65, 'z', 'a7', 9, 'b5'], ['f', 98, 'm', 't', 23, 'a1', 'a8', 14, 'b6'], ['g', 3, 'n', 'u', 1, 'a2', 'a9', 45, 'b7']] columns = pd.MultiIndex.from_tuples(list(zip(level_1, level_2))) df1 = pd.DataFrame(data, columns=columns) date = ['1/1/2023','1/2/2023','1/3/2023','1/4/2023','1/5/2023','1/6/2023','1/7/2023'] df1.insert(0, 'date', date) df1.set_index('date', inplace=True)
当前循环实现方式
我已经用循环实现了需求,但希望找到更高效的无循环方案:
for column_name in df1.columns.get_level_values(0).unique(): df1.loc[(df1[column_name, 'b_1'] > 30) | (df1[column_name, 'a_1'] == 'c'), (column_name,'e_1')] = 1 df1 = df1.reindex(columns=['A1','B1','C1'], level=0)
无循环高效解决方案
利用pandas的向量化操作和分组功能,直接批量处理所有level_1分组:
方法一:基于xs提取列+条件计算
# 提取所有分组下的a_1和b_1列 a_cols = df1.xs('a_1', level=1, axis=1) b_cols = df1.xs('b_1', level=1, axis=1) # 计算每组的条件:b_1>30 或 a_1等于'c' condition = (b_cols > 30) | (a_cols == 'c') # 将结果列转换为多级列,level_2设为'e_1' condition.columns = pd.MultiIndex.from_tuples([(col, 'e_1') for col in condition.columns]) # 合并到原DataFrame,将布尔值转为int(满足为1,否则NaN) df1 = df1.join(condition.astype(int)) # 按指定level_1顺序重排列(可选) df1 = df1.reindex(columns=['A1','B1','C1'], level=0)
方法二:基于groupby分组处理
# 按level_1分组,对每组计算条件 new_e_cols = df1.groupby(level=0, axis=1).apply( lambda group: (group['b_1'] > 30) | (group['a_1'] == 'c') ).astype(int) # 重命名列的level_2为'e_1' new_e_cols.columns = pd.MultiIndex.from_tuples([(col, 'e_1') for col in new_e_cols.columns]) # 合并到原DataFrame并调整列顺序 df1 = df1.join(new_e_cols).reindex(columns=['A1','B1','C1'], level=0)
这两种方法都避免了循环,利用pandas的内置向量化运算,在分组数量较多时效率会远高于循环实现,同时能自动适配动态变化的level_1分组(新增或删除分组时无需修改代码)。
内容的提问来源于stack exchange,提问作者scstx
相关产品推荐
相关产品推荐

