使用Pandas高效合并DataFrame:基于字符串键提取与映射的教程

心靈之曲
发布: 2025-09-04 16:43:01
原创
144人浏览过

使用Pandas高效合并DataFrame:基于字符串键提取与映射的教程

本教程详细阐述了如何使用Python Pandas库,在两个DataFrame之间进行条件合并。当合并键存在于一个DataFrame的字符串列中,且需要提取数字部分与另一个DataFrame的索引或数字列匹配时,本教程提供了一种高效的解决方案。通过str.extract方法提取关键数字,并结合map函数实现精确的数据映射,从而避免了低效的循环操作,确保了代码的性能与可读性。

场景描述

在数据处理过程中,我们经常会遇到需要将两个数据集(dataframe)进行合并或关联的情况。然而,合并键的格式可能不尽相同,例如,一个dataframe的键是“1st”、“2nd”这样的字符串,而另一个dataframe的键是纯数字(1、2、3)。在这种情况下,直接使用merge函数可能无法达到预期效果,需要对键进行预处理。

假设我们有两个DataFrame,df1和df2,结构如下:

df1

birthdate ceremony_number
9/30/1895 1st
7/23/1884 1st
3/29/1889 2nd
4/10/1868 3rd
4/8/1892 2nd

df2

index dates
1 1929-05-16
2 1930-04-03
3 1930-11-05

我们的目标是根据df1中的ceremony_number列(例如,从“1st”中提取“1”)与df2的索引(或一个名为index的列)进行匹配,然后将df2中的dates列添加到df1中,作为新的date_oscar列。

数据准备

首先,我们创建示例DataFrame并进行基本的数据类型转换,特别是日期列,将其转换为Pandas的datetime对象,这有助于后续的数据操作和一致性。

import pandas as pd

# 创建 df1
data1 = {
    'birthdate': {0: '9/30/1895', 1: '7/23/1884', 2: '3/29/1889',
                  3: '4/10/1868', 4: '4/8/1892'},
    'ceremony_number': {0: '1st', 1: '1st', 2: '2nd', 3: '3rd', 4: '2nd'}
}
df1 = pd.DataFrame(data1)

# 创建 df2
# 注意:df2的键是其索引,而不是一个单独的列
data2 = {'dates': {1: '1929-05-16', 2: '1930-04-03', 3: '1930-11-05'}}
df2 = pd.DataFrame(data2)

# 将日期列转换为datetime对象
df1['birthdate'] = pd.to_datetime(df1['birthdate'], format='%m/%d/%Y')
df2['dates'] = pd.to_datetime(df2['dates'], format='%Y-%m-%d')

print("原始 df1:")
print(df1)
print("\n原始 df2:")
print(df2)
登录后复制

输出:

硅基智能
硅基智能

基于Web3.0的元宇宙,去中心化的互联网,高质量、沉浸式元宇宙直播平台,用数字化重新定义直播

硅基智能 62
查看详情 硅基智能
原始 df1:
   birthdate ceremony_number
0 1895-09-30             1st
1 1884-07-23             1st
2 1889-03-29             2nd
3 1868-04-10             3rd
4 1892-04-08             2nd

原始 df2:
        dates
1  1929-05-16
2  1930-04-03
3  1930-11-05
登录后复制

核心解决方案:提取与映射

解决此问题的关键在于两个步骤:

  1. 从df1['ceremony_number']字符串中提取数字。
  2. 使用提取出的数字作为键,将df2['dates']的值映射到df1的新列中。
# 步骤1: 从 'ceremony_number' 列中提取数字
# 使用正则表达式 '^(\d+)' 匹配字符串开头的连续数字
# expand=False 确保返回一个 Series 而不是 DataFrame
# astype(int) 将提取到的字符串数字转换为整数类型,以便与 df2 的索引匹配
extracted_numbers = df1['ceremony_number'].str.extract('^(\d+)', expand=False).astype(int)

# 步骤2: 使用 map 函数将 df2['dates'] 的值映射到 df1
# map 方法接收一个 Series 或字典。当传入一个 Series 时,
# map 会使用该 Series 的索引作为查找键,Series 的值作为映射结果。
# 在这里,extracted_numbers 的每个值会作为键去 df2['dates'] 的索引中查找对应的值。
df1['date_oscar'] = extracted_numbers.map(df2['dates'])

print("\n合并后的 df1:")
print(df1)
登录后复制

输出:

合并后的 df1:
   birthdate ceremony_number date_oscar
0 1895-09-30             1st 1929-05-16
1 1884-07-23             1st 1929-05-16
2 1889-03-29             2nd 1930-04-03
3 1868-04-10             3rd 1930-11-05
4 1892-04-08             2nd 1930-04-03
登录后复制

关键技术解析

  • Series.str.extract(pat, expand=False):
    • 这是一个强大的字符串方法,用于从Series中的每个字符串元素中提取匹配正则表达式pat的子串。
    • ^(\d+) 是一个正则表达式:
      • ^ 匹配字符串的开头。
      • \d+ 匹配一个或多个数字。
      • () 创建一个捕获组,这意味着我们只提取括号内的内容。
    • expand=False 参数确保返回一个Series,其中包含每个匹配的第一个捕获组。如果设置为True,则会返回一个DataFrame。
  • Series.astype(int):
    • 将Series中的元素数据类型转换为整数。这是必要的,因为str.extract返回的是字符串,而df2的索引是整数。
  • Series.map(arg):
    • map方法是Pandas中用于元素级映射的利器。当arg是一个Series时,map会使用调用Series(这里是extracted_numbers)中的值作为键,去arg的索引中查找对应的值。
    • 如果某个键在arg的索引中找不到,则对应的结果将是NaN。

替代方案与注意事项

虽然map方法在此场景下非常高效和简洁,但也可以考虑其他方法:

  • DataFrame.merge():

    • 如果df2的匹配键是一个常规列(而不是索引),或者需要进行更复杂的合并类型(如内连接、左连接等),merge会是更通用的选择。
    • 在使用merge之前,同样需要对df1['ceremony_number']进行预处理,提取出数字,并可能需要重置df2的索引使其成为一个常规列。
    • 例如:
      # df2_temp = df2.reset_index().rename(columns={'index': 'ceremony_index'})
      # df1['temp_key'] = df1['ceremony_number'].str.extract('^(\d+)', expand=False).astype(int)
      # merged_df = pd.merge(df1, df2_temp, left_on='temp_key', right_on='ceremony_index', how='left')
      # df1['date_oscar'] = merged_df['dates']
      # df1.drop(columns=['temp_key'], inplace=True)
      登录后复制

      可以看出,map在添加单一列的场景下更为直接。

  • 性能考量:

    • 避免使用Python原生的for循环遍历DataFrame行,因为这通常效率低下,尤其对于大型数据集。Pandas的str访问器和map等方法都是高度优化的矢量化操作,能够显著提高性能。
  • 缺失值处理:

    • 如果extracted_numbers中的某个值在df2['dates']的索引中找不到对应的项,map操作会自动填充NaN(Not a Number)值。在实际应用中,你可能需要进一步处理这些NaN值,例如填充默认值或删除包含NaN的行。

总结

本教程展示了如何利用Pandas的str.extract和map方法,高效地解决两个DataFrame之间基于字符串键提取数字进行数据关联的问题。这种方法不仅代码简洁,而且由于使用了Pandas的矢量化操作,性能也远优于传统的循环处理方式。掌握这些技巧,将有助于你更灵活、高效地处理复杂的数据合并任务。

以上就是使用Pandas高效合并DataFrame:基于字符串键提取与映射的教程的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

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