如何基于DataFrame的key列用Numpy高效映射多列?
高效实现按Key列保留对应DataFrame列值(替代逐列numpy.select)
需求场景
已知DataFrame存在key列,需根据key值保留指定列的有效值,其余列设为NA:
key1→ 保留colA、colDkey2→ 保留colBkey3→ 保留colC
原逐列调用numpy.select的方式效率较低,需用向量化方法优化。
示例数据
先构造用于测试的样本DataFrame:
import pandas as pd import numpy as np df = pd.DataFrame({ 'key': ['key1', 'key2', 'key3', 'key1', 'key2'], 'colA': [1, 2, 3, 4, 5], 'colB': [6, 7, 8, 9, 10], 'colC': [11, 12, 13, 14, 15], 'colD': [16, 17, 18, 19, 20] }) # 定义key与保留列的映射关系 key_col_map = { 'key1': ['colA', 'colD'], 'key2': ['colB'], 'key3': ['colC'] }
最优方案:Numpy向量化掩码实现
通过生成布尔掩码矩阵,一次性完成所有列的筛选,完全避免逐列循环:
# 将每行的key映射为对应的保留列列表 key_to_cols = df['key'].map(key_col_map) # 提取除key外的所有列名数组 target_cols = df.columns.drop('key').to_numpy() # 生成掩码:每行中属于保留列的位置标记为True,其余为False mask = np.array([np.isin(target_cols, cols_list) for cols_list in key_to_cols]) # 应用掩码,保留有效值,其余设为NaN result_df = df.drop('key', axis=1).where(mask) # 补回key列 result_df['key'] = df['key']
效果说明
执行后result_df的结果为:
| colA | colB | colC | colD | key |
|---|---|---|---|---|
| 1.0 | NaN | NaN | 16.0 | key1 |
| NaN | 7.0 | NaN | NaN | key2 |
| NaN | NaN | 13.0 | NaN | key3 |
| 4.0 | NaN | NaN | 19.0 | key1 |
| NaN | 10.0 | NaN | NaN | key2 |
效率优势
该方案基于Numpy的广播和向量化运算,时间复杂度为O(n*m)(n为行数,m为列数),但比逐列处理的常数项低一个数量级以上,在大数据量场景下提升显著。
备选方案:Pandas Apply实现
如果对代码简洁性要求更高,可使用apply逐行处理(效率略低于Numpy方案):
def filter_row(row): keep_cols = key_col_map[row['key']] + ['key'] return row.where(row.index.isin(keep_cols)) result_df = df.apply(filter_row, axis=1)
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

