You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pandas中利用向量化实现动态组合列名取值?

问题描述

我正在学习Pandas,需要找到高效的计算方法:如何根据每行中'a'和'b'列的值,组合成如aX_bY_name、aX_bY_foo_bar格式的唯一列名,并取出对应列的值?

初始数据示例

indexaba1_b1_namea1_b1_foo_bara2_b1_namea2_b1_foo_bara1_b2_namea1_b2_foo_bara2_b2_namea2_b2_foo_bara1_b3_namea1_b3_foo_bara2_b3_namea2_b3_foo_bar
012value1value2value3value4value5value6value7value8value9value10value11value12
121value13value14value15value16value17value18value19value20value21value22value23value24
222value25value26value27value28value29value30value31value32value33value34value35value36
311value37value38value39value40value41value42value43value44value45value46value47value48
423value49value50value51value52value53value54value55value56value57value58value59value60

期望结果

indexnamefoo_bar
0value5value6
1value15value16
2value31value32
3value37value38
4value59value60

当前使用循环实现,但效率极低,代码如下:

for col in df.columns:
     df['name'] = np.where(col == 'a' + (df['a'].astype('Int16').astype(str)) + '_b' + (df['b'].astype('Int16').astype(str)) + '_name', df[col].values, df['name'])

高效解决方案

以下是几种基于Pandas向量化操作的实现,完全避免循环,适配数万行数据的场景:

方法1:使用df.lookup(简洁高效)

lookup可以直接根据行、列索引对批量取值,是这类场景的最优解之一:

import pandas as pd

# 构造每行对应的目标列名
name_cols = 'a' + df['a'].astype(str) + '_b' + df['b'].astype(str) + '_name'
foo_cols = 'a' + df['a'].astype(str) + '_b' + df['b'].astype(str) + '_foo_bar'

# 批量取值并生成结果表
result = pd.DataFrame({
    'name': df.lookup(df.index, name_cols),
    'foo_bar': df.lookup(df.index, foo_cols)
})

方法2:向量化索引(适配Pandas 2.0+)

若你的Pandas版本≥2.0,lookup已被标记为过时,可改用numpy数组索引实现:

import numpy as np

# 建立列名到索引的映射,加快查找速度
col_idx_map = {col: idx for idx, col in enumerate(df.columns)}

# 获取每行目标列的索引位置
name_col_indices = name_cols.map(col_idx_map)
foo_col_indices = foo_cols.map(col_idx_map)

# 从numpy数组中批量取值
df_np = df.to_numpy()
result = pd.DataFrame({
    'name': df_np[np.arange(len(df)), name_col_indices],
    'foo_bar': df_np[np.arange(len(df)), foo_col_indices]
})

方法3:重塑数据结构(适配多后缀扩展)

如果后续需要处理更多类似name/foo_bar的后缀,可先将宽表转为长表再匹配筛选:

# 宽表转长表,拆分列名为三部分
melted = df.melt(id_vars=['a', 'b'], var_name='col')
melted[['a_col', 'b_col', 'suffix']] = melted['col'].str.split('_', expand=True)

# 统一格式后匹配a/b列与拆分出的标识
melted['a_col'] = melted['a_col'].str.replace('a', '').astype(int)
melted['b_col'] = melted['b_col'].str.replace('b', '').astype(int)
matched = melted[(melted['a_col'] == melted['a']) & (melted['b_col'] == melted['b'])]

# 重塑为目标格式
result = matched.pivot(index=matched.index, columns='suffix', values='value').rename_axis(None, axis=1)

性能说明
  • 循环方法:时间复杂度为O(n*m)(n为行数,m为列数),数万行数据会明显卡顿。
  • 向量化方法:时间复杂度为O(n),性能提升至少一个数量级,甚至更高。

内容的提问来源于stack exchange,提问作者sergeyvyazov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 19:44:56