0

0

Pandas高效合并DataFrame:避免列重复并保持列顺序

碧海醫心

碧海醫心

发布时间:2025-11-19 14:21:14

|

809人浏览过

|

来源于php中文网

原创

Pandas高效合并DataFrame:避免列重复并保持列顺序

本教程旨在解决pandas中合并多个大型dataframe时遇到的列重复和内存效率问题。当dataframe已按索引对齐,且`pd.merge`因列数过多导致性能瓶颈时,我们将深入探讨如何利用`pd.dataframe.update`方法,结合列集合操作,高效地将多个dataframe合并为一个,同时避免列名冲突、保持列顺序,并有效管理内存,特别适用于具有相同id列且行数一致的数据集。

引言:Pandas DataFrame合并的挑战

在数据处理中,我们经常需要将多个DataFrame合并成一个。Pandas提供了强大的pd.merge函数,但当面临以下特定场景时,其局限性会变得突出:

  1. 大量列(Wide DataFrames): 每个DataFrame包含数万列,例如40,000列以上。
  2. 重复列名: 除了作为合并键的列(如id),多个DataFrame中还存在其他同名列。
  3. 内存效率: pd.merge在处理重复列时会添加_x和_y后缀,这会创建额外的列,对于极宽的DataFrame而言,不仅增加内存消耗,后续清理也变得非常耗时。
  4. 数据对齐: 所有DataFrame都基于一个共同的键(如id列)进行对齐,并且行数一致,意味着它们实际上是同一组记录的不同属性集合。

在这种情况下,pd.merge即使配合suffixes选项,也难以高效地完成任务。本教程将介绍一种基于pd.DataFrame.update的替代方案,它更适合处理这种场景。

pd.DataFrame.update方法简介

pd.DataFrame.update方法用于将一个DataFrame中的非NA值更新到另一个DataFrame中。它的核心特点是:

  • 按索引和列名对齐: 它会根据目标DataFrame和源DataFrame的索引和列名进行匹配。
  • 非NA值更新: 源DataFrame中的非NA值会覆盖目标DataFrame中对应的位置。
  • 不创建新列: 如果源DataFrame中存在目标DataFrame中没有的列,这些列会被添加到目标DataFrame中。如果源DataFrame中的列在目标DataFrame中已存在,则会更新其值,而不会创建新的重复列。

正是由于这些特性,update方法成为了解决上述合并问题的理想选择。

使用update方法合并DataFrame

以下是使用pd.DataFrame.update方法合并多个DataFrame的具体步骤和示例。

示例数据准备

我们首先定义三个示例DataFrame,它们都包含一个id键,以及一些共享和独有的列。

import pandas as pd
from functools import reduce

df1 = pd.DataFrame({
  'id': ['a', 'b', 'c'],
  'col1': [123, 121, 111],
  'col2': [456, 454, 444],
  'col3': [786, 787, 777],
})

df2 = pd.DataFrame({
  'id': ['a', 'b', 'c'],
  'col1': [123, 121, 111],
  'col2': [456, 454, 444],
  'col4': [11, 44, 77],
})

df3 = pd.DataFrame({
  'id': ['a', 'b', 'c'],
  'col1': [123, 121, 111],
  'col2': [456, 454, 444],
  'col5': [1786, 1787, 1777],
})

# 将所有DataFrame放入一个列表中
dfs = [df1, df2, df3]

步骤一:收集所有唯一的列名并确定最终顺序

为了确保最终DataFrame包含所有必要的列,并且保持我们期望的列顺序,我们需要首先收集所有输入DataFrame的列名集合。

# 使用functools.reduce和集合的union操作来获取所有唯一的列名
# sort=False 参数保持原始列的顺序,避免不必要的排序开销
all_unique_cols = reduce(lambda a, b: a.union(b, sort=False),
                         (x.columns for x in dfs))

print("所有唯一列名及其顺序:", all_unique_cols.tolist())
# 预期输出: ['id', 'col1', 'col2', 'col3', 'col4', 'col5']

这里,reduce函数迭代dfs列表中的每个DataFrame,并对其列名执行union操作。pd.Index.union方法会返回两个索引的并集,sort=False参数可以避免对结果进行排序,从而保持列的原始发现顺序。

步骤二:初始化目标DataFrame

接下来,我们创建一个空的或基于第一个DataFrame初始化的目标DataFrame。这个DataFrame将具有与所有输入DataFrame相同的索引,并包含所有唯一的列。

方法一:创建空的DataFrame

BlackBox AI
BlackBox AI

AI编程助手,智能对话问答助手

下载
# 基于第一个DataFrame的索引和所有唯一列名创建一个空的DataFrame
# 这样可以确保最终DataFrame的行数和索引与输入一致
final_df = pd.DataFrame(index=dfs[0].index, columns=all_unique_cols)

print("初始化后的DataFrame (方法一):\n", final_df)

这个方法会创建一个所有值为NaN的DataFrame,然后通过update逐步填充。

方法二:使用第一个DataFrame进行初始化

# 使用第一个DataFrame的内容作为基础,并确保包含所有唯一的列
# 这样可以避免第一次迭代时填充NaN值
final_df_variant = pd.DataFrame(dfs[0], columns=all_unique_cols)

print("初始化后的DataFrame (方法二):\n", final_df_variant)

这种方法在初始化时就包含了第一个DataFrame的所有数据,对于后续的update操作可能略微高效,因为它不需要填充第一个DataFrame的NaN值。

步骤三:迭代更新目标DataFrame

无论是哪种初始化方法,接下来的更新逻辑都是相同的。我们遍历所有输入DataFrame,并使用update方法将它们的数据合并到目标DataFrame中。

针对方法一的更新:

# 遍历所有DataFrame,并使用update方法将数据合并到final_df中
for df in dfs:
    final_df.update(df)

print("\n最终合并结果 (方法一):\n", final_df)

针对方法二的更新:

# 遍历除第一个DataFrame之外的其余DataFrame,并更新final_df_variant
for df in dfs[1:]: # 注意这里从第二个DataFrame开始迭代
    final_df_variant.update(df)

print("\n最终合并结果 (方法二):\n", final_df_variant)

两种方法都会产生相同的最终结果:

  id col1 col2 col3 col4  col5
0  a  123  456  786   11  1786
1  b  121  454  787   44  1787
2  c  111  444  777   77  1777

优势与注意事项

优势

  • 内存效率高: 避免了pd.merge在处理重复列时创建大量带有_x, _y后缀的中间列,显著降低内存消耗。这对于拥有数万列的DataFrame尤其重要。
  • 避免列名冲突: update方法会自动处理重复列,它会用源DataFrame中的值更新目标DataFrame中已存在的列,而不会创建新的列。
  • 保持列顺序: 通过预先收集所有列名并指定顺序,可以精确控制最终DataFrame的列顺序。
  • 适用于对齐数据: 当多个DataFrame的索引(或通过set_index设置的键)已经对齐时,此方法非常高效。

注意事项

  • 索引对齐是关键: pd.DataFrame.update是基于索引进行匹配和更新的。如果你的DataFrame不是通过id列作为索引对齐的,你需要先使用df.set_index('id', inplace=True)将id列设置为索引。在上面的示例中,由于所有DataFrame的默认整数索引是隐式对齐的(行数相同且顺序一致),所以可以直接使用。
  • 值覆盖逻辑: update方法会用源DataFrame中的非NA值覆盖目标DataFrame中的对应值。如果多个输入DataFrame在同一个共享列的同一个位置都有非NA值,那么最后被update的DataFrame的值将是最终结果。这意味着迭代顺序很重要。
  • 性能: 对于少量DataFrame和少量列,pd.merge可能更简洁。但当DataFrame数量众多、列数巨大且存在大量重复列时,update方案的性能优势会非常明显。

总结

当面对需要合并大量、宽且已按键对齐的Pandas DataFrame,同时希望避免列名重复和优化内存使用时,传统的pd.merge方法可能力不从心。本文介绍的基于pd.DataFrame.update的策略,通过预先识别所有唯一列并迭代更新目标DataFrame,提供了一个高效且内存友好的解决方案。掌握这一技巧,将使您在处理大规模复杂数据集时更加得心应手。

相关专题

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

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

51

2025.12.04

sort排序函数用法
sort排序函数用法

sort排序函数的用法:1、对列表进行排序,默认情况下,sort函数按升序排序,因此最终输出的结果是按从小到大的顺序排列的;2、对元组进行排序,默认情况下,sort函数按元素的大小进行排序,因此最终输出的结果是按从小到大的顺序排列的;3、对字典进行排序,由于字典是无序的,因此排序后的结果仍然是原来的字典,使用一个lambda表达式作为key参数的值,用于指定排序的依据。

385

2023.09.04

c语言union的用法
c语言union的用法

c语言union的用法是一种特殊的数据类型,它允许在相同的内存位置存储不同的数据类型,union的使用可以帮助我们节省内存空间,并且可以方便地在不同的数据类型之间进行转换。使用union时需要注意对应的成员是有效的,并且只能同时访问一个成员。本专题为大家提供union相关的文章、下载、课程内容,供大家免费下载体验。

123

2023.09.27

Golang gRPC 服务开发与Protobuf实战
Golang gRPC 服务开发与Protobuf实战

本专题系统讲解 Golang 在 gRPC 服务开发中的完整实践,涵盖 Protobuf 定义与代码生成、gRPC 服务端与客户端实现、流式 RPC(Unary/Server/Client/Bidirectional)、错误处理、拦截器、中间件以及与 HTTP/REST 的对接方案。通过实际案例,帮助学习者掌握 使用 Go 构建高性能、强类型、可扩展的 RPC 服务体系,适用于微服务与内部系统通信场景。

8

2026.01.15

公务员递补名单公布时间 公务员递补要求
公务员递补名单公布时间 公务员递补要求

公务员递补名单公布时间不固定,通常在面试前,由招录单位(如国家知识产权局、海关等)发布,依据是原入围考生放弃资格,会按笔试成绩从高到低递补,递补考生需按公告要求限时确认并提交材料,及时参加面试/体检等后续环节。要求核心是按招录单位公告及时响应、提交材料(确认书、资格复审材料)并准时参加面试。

37

2026.01.15

公务员调剂条件 2026调剂公告时间
公务员调剂条件 2026调剂公告时间

(一)符合拟调剂职位所要求的资格条件。 (二)公共科目笔试成绩同时达到拟调剂职位和原报考职位的合格分数线,且考试类别相同。 拟调剂职位设置了专业科目笔试条件的,专业科目笔试成绩还须同时达到合格分数线,且考试类别相同。 (三)未进入原报考职位面试人员名单。

52

2026.01.15

国考成绩查询入口 国考分数公布时间2026
国考成绩查询入口 国考分数公布时间2026

笔试成绩查询入口已开通,考生可登录国家公务员局中央机关及其直属机构2026年度考试录用公务员专题网站http://bm.scs.gov.cn/pp/gkweb/core/web/ui/business/examResult/written_result.html,查询笔试成绩和合格分数线,点击“笔试成绩查询”按钮,凭借身份证及准考证进行查询。

8

2026.01.15

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

65

2026.01.14

php与html混编教程大全
php与html混编教程大全

本专题整合了php和html混编相关教程,阅读专题下面的文章了解更多详细内容。

36

2026.01.13

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 7.2万人学习

Django 教程
Django 教程

共28课时 | 3.1万人学习

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

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