0

0

高效选取Pandas DataFrame特定元素的向量化方法

花韻仙語

花韻仙語

发布时间:2025-10-16 09:49:01

|

798人浏览过

|

来源于php中文网

原创

高效选取Pandas DataFrame特定元素的向量化方法

本文探讨了如何在pandas dataframe中,根据一个series提供行索引和列标签的映射关系,高效、向量化地选取特定元素。通过介绍`factorize`结合`reindex`和`merge`两种主要方法,详细阐述了如何避免低效的循环操作,实现性能优化,并提供了具体的代码示例和注意事项。

在数据分析和处理中,我们经常需要从Pandas DataFrame中提取特定位置的元素。一个常见的场景是,我们有一个DataFrame,以及一个Series。这个Series的索引对应DataFrame的列名,而Series的值则对应DataFrame的行索引。我们的目标是根据这种映射关系,高效地提取DataFrame中对应位置的元素,并返回一个Series或列表。

传统的做法可能会采用迭代Series的方式,逐个查找并赋值,例如:

import pandas as pd

# 假设 df 和 sr 已定义
# result = pd.Series()
# for c, i in sr.items():
#     result[c] = df.loc[i, c]

这种方法虽然直观,但对于大型数据集而言,其性能瓶颈在于循环操作,无法充分利用Pandas和NumPy的向量化优势,导致效率低下。本文将介绍两种更高效、向量化的解决方案。

示例数据

为了更好地说明问题和解决方案,我们首先定义一个示例DataFrame和Series:

import pandas as pd
import numpy as np

# 示例 DataFrame
data = np.arange(25).reshape(5, 5)
df = pd.DataFrame(data, columns=list('abcde'))
print("DataFrame (df):\n", df)

# 示例 Series
sr = pd.Series({'a': 1, 'c': 2, 'b': 3})
print("\nSeries (sr):\n", sr)

输出:

DataFrame (df):
    a   b   c   d   e
0   0   1   2   3   4
1   5   6   7   8   9
2  10  11  12  13  14
3  15  16  17  18  19
4  20  21  22  23  24

Series (sr):
a    1
c    2
b    3
dtype: int64

我们的目标是根据sr的映射关系:

  • sr['a'] = 1 对应 df.loc[1, 'a'] 即 5
  • sr['c'] = 2 对应 df.loc[2, 'c'] 即 12
  • sr['b'] = 3 对应 df.loc[3, 'b'] 即 16 最终得到一个Series:{'a': 5, 'c': 12, 'b': 16}。

方法一:利用 factorize 和 reindex 进行二维查找

这种方法的核心思想是将DataFrame的行索引和列标签以及Series中的对应值,都转换为整数位置编码。然后,通过reindex对DataFrame进行对齐,最后利用NumPy的二维数组索引能力进行高效查找。

步骤详解:

  1. 编码Series的值和索引: 使用pd.factorize()将sr的值(行索引)和sr的索引(列标签)分别转换为整数编码及其对应的唯一标签列表。

    a_i, idx = pd.factorize(sr)       # a_i 是 sr 值的整数编码,idx 是 sr 值的唯一列表
    a_c, col = pd.factorize(sr.index) # a_c 是 sr 索引的整数编码,col 是 sr 索引的唯一列表
    • a_i 将是 [1, 2, 3] (对应 sr 的值 1, 2, 3 在 idx 中的位置)
    • idx 将是 [1, 2, 3] (sr 值的唯一集合)
    • a_c 将是 [0, 1, 2] (对应 sr 索引 a, c, b 在 col 中的位置)
    • col 将是 ['a', 'c', 'b'] (sr 索引的唯一集合)
  2. 对齐DataFrame: 使用df.reindex(index=idx, columns=col)根据sr中涉及到的行索引和列标签来重新排列DataFrame。这会创建一个新的DataFrame视图,其行索引和列名与idx和col完全匹配。

    reindexed_df = df.reindex(index=idx, columns=col)

    此时,reindexed_df的形状和内容已经准备好,可以与a_i和a_c的整数编码进行对应。

    Bertha.ai
    Bertha.ai

    一款专为WordPress打造的AI内容和图像创建工具

    下载
  3. 执行二维数组查找: 将reindexed_df转换为NumPy数组,然后利用a_i和a_c作为行和列的整数索引进行查找。

    extracted_values = reindexed_df.to_numpy()[a_i, a_c]

    [a_i, a_c] 构成了 (行索引数组, 列索引数组) 的形式,NumPy会根据这些对应位置提取元素。

  4. 构建结果Series: 将提取到的值extracted_values与原始sr的索引重新组合,形成最终的Series。

    out = pd.Series(extracted_values, index=sr.index)

完整代码示例:

# 方法一:利用 factorize 和 reindex
a_i, idx = pd.factorize(sr)
a_c, col = pd.factorize(sr.index)

out_factorize = pd.Series(df.reindex(index=idx, columns=col).to_numpy()[a_i, a_c],
                          index=sr.index)
print("\n方法一结果 (factorize):\n", out_factorize)

输出:

方法一结果 (factorize):
 a     5
c    12
b    16
dtype: int64

方法二:利用 merge 进行数据融合

另一种方法是利用Pandas的merge操作。这种方法通常在数据转换和重塑时非常有用,但可能比factorize方法稍微复杂一些。

步骤详解:

  1. 重塑 sr: 将sr转换为一个DataFrame,使其索引成为一个常规列,方便后续合并。

    sr_df = sr.reset_index() # 结果是 DataFrame: 'index' | 0
                             #                  'a'     | 1
                             #                  'c'     | 2
                             #                  'b'     | 3
  2. 重塑 df: 将df堆叠(stack)成一个Series,其索引将是多级索引 (行索引, 列标签)。然后给这个Series命名,方便后续合并。

    df_stacked = df.stack().rename('out')
    # df_stacked 的索引格式为 (行索引, 列标签)
    # 例如:(0, 'a') -> 0, (0, 'b') -> 1, ...
  3. 执行合并操作: 将sr_df与df_stacked进行合并。

    • left_on=[0, 'index']: sr_df的0列(原sr的值,即DataFrame的行索引)和'index'列(原sr的索引,即DataFrame的列标签)作为合并键。
    • right_index=True: df_stacked的索引(多级索引 (行索引, 列标签))作为合并键。
    • how='left': 左合并,保留sr_df的所有记录。
      merged_df = sr_df.merge(df_stacked,
                            left_on=[0, 'index'],
                            right_index=True,
                            how='left')
  4. 整理结果: 合并后的DataFrame包含原始sr的信息以及从df中提取的值。我们需要将其整理回原始sr的索引和结构。

    out_merge = merged_df.set_index('index')['out']

完整代码示例:

# 方法二:利用 merge
out_merge = (sr.reset_index()
               .merge(df.stack().rename('out'),
                      left_on=[0, 'index'],
                      right_index=True,
                      how='left')
              .set_index('index')['out']
            )
print("\n方法二结果 (merge):\n", out_merge)

输出:

方法二结果 (merge):
 index
a     5
c    12
b    16
Name: out, dtype: int64

请注意,merge方法的结果Series的name可能会有所不同,但内容是相同的。

注意事项

  • sr 索引重复的处理: 上述两种向量化方法在处理sr的索引存在重复时,与原始的迭代循环行为可能不同。如果sr的索引有重复,例如 sr = pd.Series({'a': 1, 'c': 2, 'b': 3, 'a': 4}),原始循环会取最后一个'a'对应的值(df.loc[4, 'a'])。而factorize方法会根据sr的顺序处理,merge方法则可能返回多个匹配项。 如果需要模拟原始循环“取最后一个”的行为,应在执行向量化操作前对sr进行预处理,例如:

    # 如果 sr 的索引可能重复,且希望保留最后一个匹配项
    sr_cleaned = sr[~sr.index.duplicated(keep='last')]
    # 然后将 sr_cleaned 代替 sr 用于上述方法

    这会确保每个唯一的sr索引只对应一个值。

  • 性能考量: 通常情况下,factorize结合reindex和NumPy索引的方法在性能上会优于merge方法,尤其是在处理大规模数据时,因为它更直接地利用了底层数组操作。merge方法涉及更多的数据重塑和哈希表查找,开销相对较大。

总结

本文介绍了两种在Pandas DataFrame中高效、向量化地选取特定元素的方法,以替代低效的循环迭代。factorize结合reindex和NumPy二维索引的方法,通过将标签转换为整数位置,实现了极高的查找效率。而merge方法则通过数据重塑和融合,提供了一种更具通用性的解决方案。在实际应用中,根据数据规模和对性能的要求,可以选择最适合的方法。同时,对于sr中可能存在的索引重复问题,也提供了相应的预处理建议,以确保结果的准确性。掌握这些向量化技巧,对于提升Pandas数据处理的效率至关重要。

相关专题

更多
Python 时间序列分析与预测
Python 时间序列分析与预测

本专题专注讲解 Python 在时间序列数据处理与预测建模中的实战技巧,涵盖时间索引处理、周期性与趋势分解、平稳性检测、ARIMA/SARIMA 模型构建、预测误差评估,以及基于实际业务场景的时间序列项目实操,帮助学习者掌握从数据预处理到模型预测的完整时序分析能力。

49

2025.12.04

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

366

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

559

2023.08.10

数据分析的方法
数据分析的方法

数据分析的方法有:对比分析法,分组分析法,预测分析法,漏斗分析法,AB测试分析法,象限分析法,公式拆解法,可行域分析法,二八分析法,假设性分析法。php中文网为大家带来了数据分析的相关知识、以及相关文章等内容。

450

2023.07.04

数据分析方法有哪几种
数据分析方法有哪几种

数据分析方法有:1、描述性统计分析;2、探索性数据分析;3、假设检验;4、回归分析;5、聚类分析。本专题为大家提供数据分析方法的相关的文章、下载、课程内容,供大家免费下载体验。

263

2023.08.07

网站建设功能有哪些
网站建设功能有哪些

网站建设功能包括信息发布、内容管理、用户管理、搜索引擎优化、网站安全、数据分析、网站推广、响应式设计、社交媒体整合和电子商务等功能。这些功能可以帮助网站管理员创建一个具有吸引力、可用性和商业价值的网站,实现网站的目标。

718

2023.10.16

数据分析网站推荐
数据分析网站推荐

数据分析网站推荐:1、商业数据分析论坛;2、人大经济论坛-计量经济学与统计区;3、中国统计论坛;4、数据挖掘学习交流论坛;5、数据分析论坛;6、网站数据分析;7、数据分析;8、数据挖掘研究院;9、S-PLUS、R统计论坛。想了解更多数据分析的相关内容,可以阅读本专题下面的文章。

498

2024.03.13

Python 数据分析处理
Python 数据分析处理

本专题聚焦 Python 在数据分析领域的应用,系统讲解 Pandas、NumPy 的数据清洗、处理、分析与统计方法,并结合数据可视化、销售分析、科研数据处理等实战案例,帮助学员掌握使用 Python 高效进行数据分析与决策支持的核心技能。

71

2025.09.08

桌面文件位置介绍
桌面文件位置介绍

本专题整合了桌面文件相关教程,阅读专题下面的文章了解更多内容。

0

2025.12.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 0.6万人学习

Rust 教程
Rust 教程

共28课时 | 3.9万人学习

Git 教程
Git 教程

共21课时 | 2.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号