如何在 Pandas 中根据另一列的值动态选取指定列的元素

发布时间 - 2026-01-02 00:00:00    点击率:

本文介绍一种高效、向量化的方法,利用 `pd.factorize` 和 numpy 索引,在大型 dataframe 中根据某列指定的列名,从源 dataframe 中按行提取对应列的值。

在实际数据分析中,常遇到“列名由另一列动态决定”的场景:例如,df1['idx'] 存储了要查询的列名(如 "a" 或 "b"),而真实数值存储在另一个结构对齐的 DataFrame df 中。目标是为每一行,依据 df1.idx 的值,从 df 的对应列中取出该行的值——且需兼顾性能,避免 .apply() 或 Python 循环。

以下是最优解法(纯向量化、无显式循环):

import pandas as pd
import numpy as np

# 构造示例数据
df = pd.DataFrame({'a': [94, 170, 5],
                   'b': [31, 115, 8]}, index=[11, 12, 13])
df1 = pd.DataFrame({'idx': ["a", "b", "a"]}, index=[11, 12, 13])

# 核心步骤:向量化列查找
idx_codes, col_labels = pd.factorize(df1['idx'])  # 将列名映射为整数编码
# reindex 使 df 行索引与 df1 对齐,并仅保留所需列(去重后)
aligned_df = df.reindex(index=df1.index, columns=col_labels)
# 使用 NumPy 高级索引:每行取 idx_codes[i] 列的值
result = aligned_df.to_numpy()[np.arange(len(df1)), idx_codes]

print(result)  # [ 94 115   5]

将结果作为新列加入 df1:

df1['out'] = result
print(df1)
#     idx  out
# 11   a   94
# 12   b  115
# 13   a    5

为什么高效?

  • pd.factorize 时间复杂度接近 O(n),远优于 map 或 apply;
  • reindex(columns=...) 是列级筛选,不触发行拷贝;
  • to_numpy() + NumPy 高级索引([row_indices, col_indices])是底层 C 实现,内存连续、零 Python 解释开销。

⚠️ 注意事项:

  • 要求 df 与 df1 的索引完全对齐(或至少 df1.index 是 df.index 的子集),否则 reindex(index=...) 会引入 NaN;
  • df1['idx'] 中的列名必须全部存在于 df.columns 中,否则 reindex(columns=...) 会填充 NaN —— 建议提前校验:assert set(df1['idx']).issubset(df.columns);
  • 若存在缺失列名,可改用 df.lookup(df1.index, df1['idx'])(但注意:DataFrame.lookup 在较新 Pandas 版本中已被弃用,且对重复索引支持不佳,不推荐用于生产环境)。

该方法适用于百万级行数据,实测在 100 万行 × 数十列场景下耗时稳定在毫秒级,是处理“列名驱动索引”问题的工业级首选方案。


# python  # 编码  # app  # 为什么 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel如何为API生成Swagger或OpenAPI文档  微信小程序 闭包写法详细介绍  Laravel如何实现API资源集合?(Resource Collection教程)  laravel服务容器和依赖注入怎么理解_laravel服务容器与依赖注入解析  Laravel如何集成第三方登录_Laravel Socialite实现微信QQ微博登录  如何在云主机上快速搭建多站点网站?  Laravel辅助函数有哪些_Laravel Helpers常用助手函数大全  什么是JavaScript解构赋值_解构赋值有哪些实用技巧  关于BootStrap modal 在IOS9中不能弹出的解决方法(IOS 9 bootstrap modal ios 9 noticework)  Laravel定时任务怎么设置_Laravel Crontab调度器配置  Laravel怎么实现前端Toast弹窗提示_Laravel Session闪存数据Flash传递给前端【方法】  如何用y主机助手快速搭建网站?  iOS正则表达式验证手机号、邮箱、身份证号等  JavaScript如何实现错误处理_try...catch如何捕获异常?  晋江文学城电脑版官网 晋江文学城网页版直接进入  js实现点击每个li节点,都弹出其文本值及修改  html5源代码发行怎么设置权限_访问权限控制方法与实践【指南】  如何基于云服务器快速搭建个人网站?  网站制作大概要多少钱一个,做一个平台网站大概多少钱?  HTML5打空格有哪些误区_新手常犯的空格使用错误【技巧】  Linux虚拟化技术教程_KVMQEMU虚拟机安装与调优  HTML5段落标签p和br怎么选_文本排版常用标签对比【解答】  利用JavaScript实现拖拽改变元素大小  高端网站建设与定制开发一站式解决方案 中企动力  教你用AI将一段旋律扩展成一首完整的曲子  用v-html解决Vue.js渲染中html标签不被解析的问题  Laravel表单请求验证类怎么用_Laravel Form Request分离验证逻辑教程  javascript读取文本节点方法小结  如何在Ubuntu系统下快速搭建WordPress个人网站?  python中快速进行多个字符替换的方法小结  移动端脚本框架Hammer.js  如何在Windows 2008云服务器安全搭建网站?  lovemo网页版地址 lovemo官网手机登录  Laravel队列由Redis驱动怎么配置_Laravel Redis队列使用教程  Python制作简易注册登录系统  如何登录建站主机?访问步骤全解析  javascript如何操作浏览器历史记录_怎样实现无刷新导航  高端建站如何打造兼具美学与转化的品牌官网?  如何在阿里云部署织梦网站?  如何在七牛云存储上搭建网站并设置自定义域名?  Laravel如何使用查询构建器?(Query Builder高级用法)  logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?  原生JS获取元素集合的子元素宽度实例  java中使用zxing批量生成二维码立牌  如何在IIS服务器上快速部署高效网站?  如何做网站制作流程,*游戏网站怎么搭建?  EditPlus中的正则表达式 实战(1)  Laravel怎么发送邮件_Laravel Mail类SMTP配置教程  LinuxShell函数封装方法_脚本复用设计思路【教程】  儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?