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

高效选取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 pdimport numpy as np# 示例 DataFramedata = np.arange(25).reshape(5, 5)df = pd.DataFrame(data, columns=list('abcde'))print("DataFrame (df):n", df)# 示例 Seriessr = pd.Series({'a': 1, 'c': 2, 'b': 3})print("nSeries (sr):n", sr)

输出:

DataFrame (df):    a   b   c   d   e0   0   1   2   3   41   5   6   7   8   92  10  11  12  13  143  15  16  17  18  194  20  21  22  23  24Series (sr):a    1c    2b    3dtype: int64

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

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

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

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

步骤详解:

编码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 索引的唯一集合)

对齐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的整数编码进行对应。

英特尔AI工具 英特尔AI工具

英特尔AI与机器学习解决方案

英特尔AI工具 70 查看详情 英特尔AI工具

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

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

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

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

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

完整代码示例:

# 方法一:利用 factorize 和 reindexa_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     5c    12b    16dtype: int64

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

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

步骤详解:

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

sr_df = sr.reset_index() # 结果是 DataFrame: 'index' | 0                         #                  'a'     | 1                         #                  'c'     | 2                         #                  'b'     | 3

重塑 df:将df堆叠(stack)成一个Series,其索引将是多级索引 (行索引, 列标签)。然后给这个Series命名,方便后续合并。

df_stacked = df.stack().rename('out')# df_stacked 的索引格式为 (行索引, 列标签)# 例如:(0, 'a') -> 0, (0, 'b') -> 1, ...

执行合并操作:将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')

整理结果:合并后的DataFrame包含原始sr的信息以及从df中提取的值。我们需要将其整理回原始sr的索引和结构。

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

完整代码示例:

# 方法二:利用 mergeout_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): indexa     5c    12b    16Name: 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数据处理的效率至关重要。

以上就是高效选取Pandas DataFrame特定元素的向量化方法的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/592771.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月10日 16:38:22
下一篇 2025年11月10日 16:41:43

相关推荐

  • 递归算法中列表与字符串的陷阱:Python 可变对象与不可变对象的行为差异

    本文深入探讨了在递归算法中处理Python列表(可变对象)和字符串(不可变对象)时常见的陷阱。通过一个生成不含连续1的二进制字符串的案例,详细分析了为何直接修改列表会导致意外结果,而字符串却能正常工作。文章提供了两种有效的解决方案:一种是精确控制列表状态的“回溯”方法,另一种是利用列表拼接创建新对象…

    2025年12月14日
    000
  • 如何用Python开发GUI应用?PyQt5完整项目教程

    用python开发gui应用不难,借助pyqt5可快速上手。1. 安装pyqt5并创建项目结构,使用qapplication和qwidget搭建基础窗口;2. 使用qvboxlayout等布局结合qlabel、qlineedit、qpushbutton设计温度转换器界面;3. 绑定按钮事件实现摄氏度…

    2025年12月14日 好文分享
    000
  • Pandas与NumPy:高效地从多列中条件性提取值及来源

    本文探讨了在Pandas DataFrame中根据条件从多列中提取值及其来源的常见需求。针对numpy.select无法直接返回多列的限制,文章首先介绍了分离式np.select的传统做法,随后重点阐述并演示了一种利用df.notna().to_numpy().argmax(1)结合高级索引技术,实…

    2025年12月14日
    000
  • Pandas DataFrame行内组合生成与频率统计指南

    本教程详细介绍了如何利用Pandas、itertools和collections.Counter库,高效地遍历DataFrame的每一行,生成行内所有可能的元素组合(从单个元素到所有元素),并进一步统计这些组合在整个DataFrame中的出现频率。这对于数据模式发现、特征工程或市场篮子分析等场景具有…

    2025年12月14日
    000
  • 高效统计Pandas DataFrame行内元素组合频率

    本教程详细介绍了如何高效地遍历Pandas DataFrame的每一行,生成行内所有可能的元素组合,并统计这些组合在整个DataFrame中的出现频率。通过结合使用Python的itertools.combinations函数生成组合、collections.Counter类进行频率计数,以及Pan…

    2025年12月14日
    000
  • 怎样用Python处理多级索引?MultiIndex操作指南

    python中处理pandas的multiindex核心在于掌握其创建、数据选择与切片、以及结构调整。1. multiindex可通过set_index()将列设为索引或直接构建(如from_tuples或from_product)。2. 数据选择需用loc配合元组精确匹配或多层切片,结合pd.in…

    2025年12月14日 好文分享
    000
  • 怎样用Python开发桌面应用?PyQt5入门指南

    用python开发桌面应用可通过pyqt5实现,步骤包括:1. 安装pyqt5并配置环境;2. 使用布局管理器设计界面;3. 绑定信号与槽实现交互逻辑;4. 使用pyinstaller打包发布程序。首先安装pyqt5库,运行示例代码创建基础窗口结构;接着选用qhboxlayout、qvboxlayo…

    2025年12月14日 好文分享
    000
  • Pandas DataFrame行内组合生成与频次统计教程

    本教程详细介绍了如何利用Pandas、itertools和collections.Counter库,对DataFrame的每一行数据生成所有可能的组合,并高效统计这些组合的出现频率。通过自定义函数和Pandas的apply方法,可以灵活处理行内数据,最终将统计结果转化为易于分析的DataFrame格…

    2025年12月14日
    000
  • 如何使用Python计算数据排名?rank排序方案

    1.使用pandas的rank()方法是python中计算数据排名的核心方案。它适用于series和dataframe,支持多种重复值处理方式(method=’average’/’min’/’max’/’first&…

    2025年12月14日 好文分享
    000
  • Python怎样实现数据排序?sorted函数技巧

    python中的sorted()函数可用于快速排序各种可迭代对象,默认升序排列,通过reverse=true实现降序;1.使用key参数可按自定义规则排序,如按字典字段、对象属性或字符串长度;2.可通过返回元组实现多条件排序,先按主条件再按次条件;3.sorted()返回新列表,原数据不变,而列表的…

    2025年12月14日 好文分享
    000
  • Python 垂直打印字符串列表:无需 itertools 的实现方案

    本文介绍了如何使用 Python 将字符串列表垂直打印输出,且不依赖于 itertools 库。通过循环遍历字符串列表,并逐个字符地打印,可以实现垂直排列的效果。文章提供了一种简洁明了的实现方式,并附带代码示例,方便读者理解和应用。 在某些情况下,我们可能需要将一个字符串列表以垂直的方式打印出来,例…

    2025年12月14日
    000
  • Python 垂直打印字符串列表:无需额外库的实现方案

    本文介绍了一种无需 itertools 库即可实现垂直打印字符串列表的方法。通过循环遍历字符串列表,并逐个字符地打印,可以实现将字符串垂直排列的效果。本文提供详细的代码示例,并解释了实现原理,帮助读者理解和应用该方法。 在 Python 中,有时我们需要将字符串列表垂直打印出来,即将每个字符串的相同…

    2025年12月14日
    000
  • 模糊匹配地址数据的实用教程

    本文旨在提供一种在PostgreSQL中实现模糊匹配地址和名称数据的方法。针对传统字符串匹配算法(如soundex()和levenshtein())在处理包含部分匹配和噪声词的数据时表现不佳的问题,本文将介绍如何利用pg_trgm扩展提供的相似度函数进行更有效的模糊匹配,并探讨预处理步骤(如去除噪声…

    2025年12月14日
    000
  • 基于 PostgreSQL 的模糊地址匹配教程

    本文旨在提供一个基于 PostgreSQL 的模糊地址匹配方案。我们将探讨如何利用 pg_trgm 扩展提供的相似度函数,结合噪声词移除等预处理技术,来实现高效且准确的地址模糊匹配。本教程将提供具体的 SQL 示例,并讨论在 PostgreSQL 中直接实现和使用 Python 辅助处理的优劣。 引…

    2025年12月14日
    000
  • 模糊匹配地址数据的实用指南

    本文旨在提供一套实用的地址数据模糊匹配方案,重点介绍如何利用 PostgreSQL 的 pg_trgm 扩展来提高匹配的准确性和效率。我们将探讨如何使用 similarity 函数进行模糊匹配,并讨论预处理数据以提升匹配效果的技巧,例如去除噪声词。 在处理地址数据匹配时,传统的字符串比较方法,如 s…

    2025年12月14日
    000
  • 垂直打印字符串列表:无需itertools的实现方案

    本教程旨在提供一种在Python中垂直打印字符串列表的方法,且不依赖itertools库。通过循环遍历字符串列表,并逐个字符地打印,可以实现将字符串列表以垂直方式并排显示的效果。本方案提供清晰的代码示例,并详细解释了实现逻辑,方便读者理解和应用。 在某些情况下,我们可能需要将一个字符串列表以垂直方式…

    2025年12月14日
    000
  • Python:无需 itertools 库,垂直打印多字符串

    本教程介绍如何使用 Python 垂直打印多个字符串,且不依赖 itertools 库。通过循环遍历字符串列表,并逐个字符地打印,可以实现字符串的垂直排列输出。本教程提供了一种简洁明了的方法,适用于需要在不引入额外库的情况下完成字符串处理任务的场景。 在某些情况下,我们可能需要将多个字符串垂直排列输…

    2025年12月14日
    000
  • 如何用Python进行数据预测—ARIMA时间序列建模

    arima模型适用于时间序列预测,需遵循平稳性检验、参数选择、建模与预测、评估优化四个步骤。1. 数据需平稳,可通过差分和adf检验处理;2. 通过acf/pacf图或网格搜索确定p,d,q参数;3. 使用statsmodels库训练模型并预测未来值;4. 用mae、rmse等指标评估,优化参数或引…

    2025年12月14日 好文分享
    000
  • Python怎样处理气象数据?netCDF4库使用

    python处理netcdf气象数据的核心工具是netcdf4库,其流程为:1.使用dataset()打开文件;2.通过.dimensions、.variables和.ncattrs()查看结构信息;3.读取变量数据并进行操作;4.最后关闭文件。netcdf4支持创建、修改文件及高级功能如数据压缩、…

    2025年12月14日 好文分享
    000
  • Python如何开发桌面应用?PyQt5界面设计完整教程

    pyqt5是python开发桌面应用的高效工具,1. 选择pyqt5因其功能强大、界面美观且跨平台;2. 安装需执行pip install pyqt5 pyqt5-tools以获取设计工具;3. 核心概念包括qapplication(程序入口)、qwidget(基础控件)及信号与槽机制(事件处理);…

    2025年12月14日 好文分享
    000

发表回复

登录后才能评论
关注微信