如何快速在Pandas DataFrame中批量生成数百个衍生列
问题描述
现有如下结构的Pandas DataFrame:
Group_ID feature1 feature2 label 1 3 2 0 1 5 7 0 1 2 4 1 1 9 9 1 1 2 0 1 2 4 1 1 2 8 8 0 2 5 5 0 3 0 9 1 3 4 7 1 3 2 3 0 3 7 2 0
需求:对每个feature i(如feature1、feature2),生成名为featurei_rel的新列,计算逻辑为该行feature i的值除以同Group_ID组内该feature最小两个值的均值。例如Group 1中feature1的最小两个值为2和2,该行feature1值为3时,feature1_rel=3/((2+2)/2)=1.5,期望结果如下:
Group_ID feature1 feature2 feature1_rel feature2_rel label 1 3 2 3/((2+2)/2) 2/((0+2)/2) 0 1 5 7 5/((2+2)/2) 7/((0+2)/2) 0 1 2 4 2/((2+2)/2) 4/((0+2)/2) 1 1 9 9 9/((2+2)/2) 9/((0+2)/2) 1 1 2 0 2/((2+2)/2) 0/((0+2)/2) 1 2 4 1 4/((4+5)/2) 1/((1+5)/2) 1 2 8 8 8/((4+5)/2) 8/((1+5)/2) 0 2 5 5 5/((4+5)/2) 5/((1+5)/2) 0 3 0 9 0/((0+2)/2) 9/((2+3)/2) 1 3 4 7 4/((0+2)/2) 7/((2+3)/2) 1 3 2 3 2/((0+2)/2) 3/((2+3)/2) 0 3 7 2 7/((0+2)/2) 2/((2+3)/2) 0
用户已尝试单个特征的实现代码,但实际数据集包含数百个特征及数百万行数据,需要高效批量实现的方法:
# create columns to find the smallest element in a group df['feature1min'] = df.groupby('Group_ID')['feature1'].transform('min') # create columns to find the second smallest element in a group df['feature1min2'] = df.groupby('Group_ID')['feature1'].nsmallest(2) df['feature1_rel'] = df['feature1']/((df['feature1min'] + df['feature1min2']) / 2)
高效批量实现方案
针对大数据量(数百万行+数百特征),推荐使用分组聚合+广播变换的方式,避免循环单个特征,最大化利用Pandas的向量化运算效率:
步骤1:筛选特征列
先提取所有需要处理的特征列(排除Group_ID和label):
feature_cols = [col for col in df.columns if col.startswith('feature')]
步骤2:分组计算每组最小两个值的均值
通过groupby.agg结合nsmallest,一次性计算所有特征的组内最小两个值的均值,再用transform将结果广播到原数据的每一行:
# 定义聚合函数:取组内最小的两个值,计算均值 def mean_two_smallest(x): return x.nsmallest(2).mean() # 对所有特征列分组计算均值,再映射到原数据 group_means = df.groupby('Group_ID')[feature_cols].transform(mean_two_smallest)
步骤3:批量生成_rel列
直接用原特征列除以对应的分组均值,批量创建新列:
# 批量命名并赋值新列 for col in feature_cols: df[f'{col}_rel'] = df[col] / group_means[col]
完整可运行代码
import pandas as pd # 构造示例数据 data = { 'Group_ID': [1,1,1,1,1,2,2,2,3,3,3,3], 'feature1': [3,5,2,9,2,4,8,5,0,4,2,7], 'feature2': [2,7,4,9,0,1,8,5,9,7,3,2], 'label': [0,0,1,1,1,1,0,0,1,1,0,0] } df = pd.DataFrame(data) # 1. 筛选特征列 feature_cols = [col for col in df.columns if col.startswith('feature')] # 2. 分组计算每组最小两个值的均值 def mean_two_smallest(x): return x.nsmallest(2).mean() group_means = df.groupby('Group_ID')[feature_cols].transform(mean_two_smallest) # 3. 批量生成_rel列 for col in feature_cols: df[f'{col}_rel'] = df[col] / group_means[col] # 查看结果 print(df)
效率说明
- 避免循环单个特征的冗余操作,所有特征的分组计算一次完成
- 利用Pandas向量化运算,比逐行/逐特征循环快数倍,适配数百万行的大数据集
- 无需创建额外中间列(如feature1min),节省内存开销
内容的提问来源于stack exchange,提问作者Ishigami
相关产品推荐
相关产品推荐

