【pandas数据合并实战】:pd.concat()参数详解与场景化应用

张开发
2026/4/17 22:47:06 15 分钟阅读

分享文章

【pandas数据合并实战】:pd.concat()参数详解与场景化应用
1. pd.concat()基础数据合并的瑞士军刀刚接触pandas时我最头疼的就是把几个表格拼在一起。比如上个月做销售分析华北区的数据在Excel里华东区的在CSV里华南区的又是从数据库导出的JSON。这时候pd.concat()就像个万能胶水能把这些不同来源的数据整齐地粘在一起。先看个最简单的例子假设我们有两个班级的学生名单需要合并成全校名单。用concat()只需要一行代码import pandas as pd class1 pd.DataFrame({姓名: [张三, 李四], 分数: [85, 92]}) class2 pd.DataFrame({姓名: [王五, 赵六], 分数: [78, 88]}) # 上下堆叠合并 all_students pd.concat([class1, class2])这个操作相当于把两个表格竖向粘在一起专业术语叫轴向连接。默认的axis0参数就是控制这个行为的。我刚开始总记不住axis0和1的区别后来发现可以想象成书架上的书axis0是把书竖着叠放增加高度axis1是把书横着并排增加宽度。2. 核心参数深度解析2.1 axis参数决定合并方向的选择题实际项目中我遇到过需要横向合并的场景。比如某电商的订单数据1月份的用户信息在一个表购买记录在另一个表这时候就需要axis1的横向合并user_info pd.DataFrame({用户ID: [1001, 1002], 性别: [男, 女]}) order_info pd.DataFrame({用户ID: [1001, 1002], 订单金额: [299, 599]}) # 横向合并要注意索引对齐 merged_data pd.concat([user_info.set_index(用户ID), order_info.set_index(用户ID)], axis1)这里有个坑我踩过直接横向合并会导致数据错位必须先用set_index()确保两个表按用户ID对齐。这也是为什么实际业务中merge()可能更适合这种场景但concat()的优势在于能处理列名完全不相同的表。2.2 join参数内外连接的艺术join参数控制着合并时的保留策略outer(外连接)会保留所有数据inner(内连接)只保留共有的。去年分析销售数据时就遇到这种情况product_info pd.DataFrame({ 产品ID: [A01, A02, A03], 库存量: [100, 200, 150] }) sales_data pd.DataFrame({ 产品ID: [A01, A02, A04], 销量: [30, 45, 20] }) # 外连接保留所有产品 outer_merge pd.concat([product_info.set_index(产品ID), sales_data.set_index(产品ID)], axis1, joinouter) # 内连接只保留共有产品 inner_merge pd.concat([product_info.set_index(产品ID), sales_data.set_index(产品ID)], axis1, joininner)外连接结果会包含A03和A04产品但会有NaN值内连接则只有A01和A02。根据我的经验做库存分析时用outer更合适因为需要知道哪些货根本没卖出去。2.3 ignore_index重建索引的智慧默认情况下concat()会保留原始索引这在某些场景下会产生问题。比如合并多个分表时可能会出现重复索引df1 pd.DataFrame({A: [A0, A1]}, index[0, 1]) df2 pd.DataFrame({A: [A2, A3]}, index[0, 1]) # 不忽略索引会导致重复 problematic pd.concat([df1, df2]) # 正确做法 good_merge pd.concat([df1, df2], ignore_indexTrue)ignore_indexTrue会重建0到n-1的连续索引。上个月处理物流数据时就因为这个参数没设置导致后续的loc查询出了大问题。3. 高级应用场景实战3.1 keys参数创建分层索引当需要区分合并前的数据来源时keys参数就派上用场了。它可以创建多层索引相当于给每组数据打上标签quarter1 pd.DataFrame({销售额: [100, 150]}) quarter2 pd.DataFrame({销售额: [200, 250]}) # 添加季度标识 result pd.concat([quarter1, quarter2], keys[Q1, Q2])这样生成的DataFrame可以用result.loc[Q1]快速获取第一季度数据。我在做年度报告时常用这招比手动添加标识列方便多了。3.2 处理列名不一致的情况真实数据往往不那么规整合并时经常遇到列名不完全相同的情况。concat()的默认行为是保留所有列缺失值用NaN填充staff_2022 pd.DataFrame({ 姓名: [张三, 李四], 薪资: [8000, 9000] }) staff_2023 pd.DataFrame({ 姓名: [王五, 赵六], 薪资: [8500, 9500], 奖金: [2000, 3000] # 新增列 }) combined pd.concat([staff_2022, staff_2023])这种处理方式在数据分析初期很有用可以快速查看所有可能的字段。但做统计分析前通常需要先用fillna()处理缺失值。4. 性能优化与避坑指南4.1 大数据量下的性能考量处理百万级数据时concat()的性能差异就很明显了。经过多次测试我发现预先分配好内存比反复追加要快得多对于超大数据可以考虑先用列表收集所有数据最后一次性concat设置copyFalse可以节省内存但要确保原始数据不会被修改# 高效做法 data_chunks [process_file(f) for f in all_files] final_df pd.concat(data_chunks, copyFalse)4.2 常见错误排查内存不足合并超大数据时出现MemoryError可以尝试分批次合并数据类型不一致合并后数值变对象类型需要先用astype()统一索引混乱忘记设置ignore_index导致后续操作出错列名错位横向合并时没对齐索引数据全乱套上周我就遇到个典型问题合并后所有数字都变成了字符串查了半天发现是一个源文件里的数字被写成了1,000这种格式pandas自动转换成了字符串。解决方法是在读取数据时就指定正确的数据类型。

更多文章