【Python】使用Python合并多个CSV文件(使用命令行参数运行代码进行垂直堆叠)

引言

在数据处理过程中,经常需要将多个CSV文件合并为一个文件。例如,当数据分散在多个文件中,且每个文件的结构相同时,合并可以简化后续分析。然而,合并时需注意如何处理各文件的标题行(即首行),避免重复的标题行干扰数据。


问题描述

  1. 合并多个CSV文件,上下堆叠(垂直合并),要求所合并的文件的文件头(即第一行标题行)的内容与顺序一致。
  2. 合并时,仅保留第一个文件的标题行,其他文件的标题行需跳过。
  3. 提供选项允许用户选择保留所有文件的标题行(例如调试或保留原始结构)。

示例文件

  • A.csv(首行为标题):
    name,age
    Alice,30
    Bob,25
    
  • B.csv(首行为标题):
    name,age
    Charlie,35
    David,40
    

期望合并结果(默认跳过其他文件的标题行):

name,age
Alice,30
Bob,25
Charlie,35
David,40

解决方案

我们通过Python的csvargparse模块实现以下功能:

  1. 读取多个CSV文件。
  2. 根据用户参数决定是否跳过其他文件的标题行。
  3. 将内容合并到指定输出文件。

代码实现与解析

完整代码

# -*- coding: utf-8 -*-
# @Time    : 2025/03/01 16:50
# @Author  : 哇咔咔哇咔
# @Email   : yannbao@163.com
# @File    : merge_csv.py
# @Software: PyCharm
# @Brief   : 参数式合并CSV文件工具    合并多个CSV文件,可选择保留标题行(使用参数实现)


import argparse
import csv

def merge_csv(input_files, output_file, include_all_headers):
    """
    合并多个CSV文件,可选择是否保留所有文件的标题行。
    
    :param input_files: 输入文件路径列表
    :param output_file: 输出文件路径
    :param include_all_headers: 是否保留所有标题行
    """
    with open(output_file, 'w', newline='', encoding='utf-8') as outfile:
        writer = csv.writer(outfile)
        for i, file in enumerate(input_files):
            with open(file, 'r', newline='', encoding='utf-8') as infile:
                reader = csv.reader(infile)
                # 处理第一个文件:保留所有行
                if i == 0:
                    for row in reader:
                        writer.writerow(row)
                # 处理其他文件:根据参数跳过标题行
                else:
                    if not include_all_headers:
                        try:
                            next(reader)  # 跳过首行
                        except StopIteration:
                            pass  # 处理空文件
                    for row in reader:
                        writer.writerow(row)

def main():
    parser = argparse.ArgumentParser(description='合并CSV文件,灵活处理标题行')
    parser.add_argument('files', nargs='+', help='输入CSV文件路径列表')
    parser.add_argument('-o', '--output', required=True, help='输出文件路径')
    parser.add_argument('--include-all-headers', action='store_true',
                        help='保留所有文件的标题行(默认仅保留第一个文件的标题行)')
    args = parser.parse_args()
    merge_csv(args.files, args.output, args.include_all_headers)

if __name__ == '__main__':
    main()

关键代码解析

1. 跳过标题行的逻辑

if not include_all_headers:
    try:
        next(reader)  # 跳过首行
    except StopIteration:
        pass  # 处理空文件
  • 功能:如果用户选择不保留所有标题行(include_all_headers=False),则跳过非首文件的标题行。
  • 实现
    • next(reader):读取并丢弃一行(标题行)。
    • try-except:处理空文件。若文件为空,next(reader)会抛出StopIteration异常,此处直接忽略。

2. 命令行参数设计

parser.add_argument('files', nargs='+', help='输入CSV文件路径列表')
parser.add_argument('-o', '--output', required=True, help='输出文件路径')
parser.add_argument('--include-all-headers', action='store_true', help='保留所有标题行')
  • 参数类型
    • 位置参数files):必须按顺序提供,不可省略。
    • 可选参数-o--include-all-headers):通过---指定,顺序可调整。
  • 作用
    • files:待合并的CSV文件列表。
    • -o:指定输出文件路径(必填)。
    • --include-all-headers:保留所有标题行(默认不保留)。

参数详解:-的作用与区别

在命令行中,参数分为两种类型:

1. 位置参数(无-前缀)

  • 定义必须按顺序提供,不可省略。
  • 示例
    python merge_csv.py file1.csv file2.csv -o merged.csv
    
    • file1.csvfile2.csv是位置参数,对应代码中的files

2. 可选参数(有-前缀)

  • 定义:以-(短选项)或--(长选项)开头,顺序可调整。
  • 示例
    python merge_csv.py file1.csv file2.csv --include-all-headers -o merged.csv
    
    • -o--include-all-headers是可选参数。

- 与不加 - 的区别总结

特性 不加 -(位置参数) -(可选参数)
前缀 -(短选项)或 --(长选项)
顺序 必须按定义顺序提供 可以放在任意位置
是否必须 必须提供 可选(除非设置 required=True
典型用途 输入文件路径等必须参数 输出文件路径、配置选项等

示例场景

场景1:默认合并(跳过其他标题行)

命令

python merge_csv.py A.csv B.csv -o merged.csv

输出文件内容

name,age
Alice,30
Bob,25
Charlie,35
David,40

场景2:保留所有标题行

命令

python merge_csv.py A.csv B.csv -o merged.csv --include-all-headers

输出文件内容

name,age
Alice,30
Bob,25
name,age  # B.csv的标题行被保留
Charlie,35
David,40

场景3:处理空文件

B.csv为空文件:

python merge_csv.py A.csv B.csv -o merged.csv

输出文件内容

name,age
Alice,30
Bob,25
# B.csv的内容为空,无数据写入
posted @   小白哇咔  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示