如何高效将选定特征交互项作为新列添加到pandas DataFrame
更优的特征交互项生成方案
你之前的两个方案性能差的核心原因是存在大量冗余计算:第一种循环内重复实例化、调用sklearn接口产生很多非必要开销;第二种全量计算交互项浪费了大量算力在你不需要的特征上。
方案1:直接列相乘(最简洁,仅适用于二阶交互项)
二阶交互项本质就是两个特征的逐行乘积,完全不需要调用PolynomialFeatures接口,直接用pandas列的向量运算即可:
import numpy as np import pandas as pd np.random.seed(1111) a1 = np.random.randint(2, size = (5,3)) a2 = np.round(np.random.random((5,3)),2) df = pd.DataFrame(np.concatenate([a1, a2], axis = 1), columns = ['a','b','c','d','e','f']) combinations = [['a', 'e'], ['a', 'f'], ['b', 'f']] # 直接遍历组合计算乘积 for col1, col2 in combinations: df[f"{col1} {col2}"] = df[col1] * df[col2]
运行结果和你之前用sklearn得到的完全一致。
方案2:批量向量化计算(性能最优,适合大量交互项场景)
如果需要生成的交互项数量很多,可以直接用numpy广播一次计算所有交互项,省去Python层的循环开销:
# 提取两列的数值矩阵 col1_arr = df[[c[0] for c in combinations]].values col2_arr = df[[c[1] for c in combinations]].values # 广播计算所有乘积 interact_arr = col1_arr * col2_arr # 生成列名并一次性合并到原DataFrame interact_cols = [f"{c[0]} {c[1]}" for c in combinations] df[interact_cols] = interact_arr
方案3:通用任意阶交互项生成
如果需要生成三阶及以上的交互项,可以用reduce批量相乘,适配任意长度的特征组合:
from functools import reduce import operator combinations = [['a','e','f'], ['b','c','d']] # 三阶交互组合示例 for comb in combinations: col_name = " ".join(comb) df[col_name] = reduce(operator.mul, (df[c] for c in comb), 1)
性能优势说明
- 对比循环调用sklearn的方案:省去了接口调用、拟合、特征名解析、切片索引等冗余操作,运算效率通常可以提升5~10倍。
- 对比全量生成交互项的方案:仅计算你需要的交互项,当原始特征数量多、目标交互项占比低时,内存和算力开销可以降低一个数量级以上。
内容的提问来源于stack exchange,提问作者msfrn
相关产品推荐
相关产品推荐

