【python】合并具有相同数字前缀的 CSV 文件

93 篇文章 0 订阅

一、问题

有一个文件目录,目录下有类似下列文件名:1_a.csv、1_b.csv、1_c.csv、2_a.csv、2_b.csv、2_c.csv......即下划线前面数字相同的不同csv文件有几个,他们的行数相同,列名不同。

想把这个目录下,数字相同的几个文件都合并成1个文件,例如:1_a.csv、1_b.csv、1_c.csv合并成1.csv,2_a.csv、2_b.csv、2_c.csv合并成2.csv......

二、实现

为了合并具有相同数字前缀的 CSV 文件,需要遵循以下步骤:
1. 读取目录中所有的文件名。
2. 根据文件名中的数字前缀进行分类。
3. 合并具有相同数字前缀的 CSV 文件到一个新的 CSV 文件中。
下面是实现上述步骤的 Python 脚本:

import os
import pandas as pd

# 目标目录
directory = "/home/test/datas"
directory_d = "/home/test/d"

files = os.listdir(directory)
sorted_files = {}

#print(files)

# 对文件分类,基于数字前缀
for file in files:
    if file.endswith('.csv'):
        prefix = file.split('_')[0]
        sorted_files.setdefault(prefix, []).append(file)

# 合并具有相同前缀的文件
for prefix, file_list in sorted_files.items():
    dataframes = []
    for filename in file_list:
        filepath = os.path.join(directory, filename)
        df = pd.read_csv(filepath)
        dataframes.append(df)

    # 可以假设所有数据列相同,并按顺序相同,如果不是这样,需要进行额外处理
    merged_df = pd.concat(dataframes, axis=1)
    # 处理合并后的数据列中可能存在的重复
    merged_df = merged_df.loc[:,~merged_df.columns.duplicated()]

    # 保存新的合并文件
    merged_filename = f"{directory_d}/{prefix}.csv"
    merged_df.to_csv(merged_filename, index=False)
    print(f"{directory_d}/{prefix}.csv");

print("合并完成.")

这个脚本将按照数字前缀合并所有的 CSV 文件,最后将它们保存为一个新的文件(例如 1.csv,其中包含了所有 1_*.csv 的合并数据)。该脚本假设每组文件的列数相同,仅列名称不同,并且每个文件具有相同的行顺序。合并时使用了 concat 函数,去除了重复的列名(如果存在)。

三、代码解释

这段代码是一个Python脚本,用于合并指定目录下的多个CSV文件。以下是代码的详细解释:

  1. 导入必要的库:

    • os: 用于与操作系统交互,例如读取目录内容。
    • pandas as pd: 用于数据处理和分析的库,特别是DataFrame操作。
  2. 定义目标目录:

    • directory = "/home/test/tdx_datas_min": 这是源目录,其中包含要合并的CSV文件。
    • directory_d = "/home/test/d": 这是目标目录,合并后的CSV文件将保存在这里。
  3. 获取目录中的文件列表:

    • files = os.listdir(directory): 使用os.listdir函数获取directory目录下的所有文件名。
  4. 基于数字前缀对文件进行分类:

    • 循环遍历所有文件。
    • 如果文件以.csv结尾,则使用_作为分隔符获取文件名的第一个部分(数字前缀),并将该文件添加到具有相同前缀的列表中。
  5. 合并具有相同前缀的文件:

    • 循环遍历每个前缀及其对应的文件列表。
    • 对于每个文件,读取其内容并将其存储为一个pandas DataFrame。
    • 所有具有相同前缀的文件的内容都存储在一个列表中。
    • 使用pd.concat函数按列(axis=1)合并这些数据框。这意味着它将尝试将具有相同列名的列合并在一起。
    • 使用merged_df.loc[:,~merged_df.columns.duplicated()]处理可能存在的重复列名,删除重复的列。
  6. 保存合并后的文件:

    • 使用前缀作为新文件名的一部分,将合并后的数据框保存为CSV文件在目标目录中。
  7. 输出信息:

    • 打印“合并完成.”表示操作已完成。

注意事项:

  • 这个脚本假设所有要合并的CSV文件都有相同的列,并且列的顺序也是相同的。如果不是这样,合并操作可能会导致错误或意外的结果。在实际应用中,可能需要更多的检查和处理步骤来确保合并的正确性。

四、代码段1的解释

代码段1

f"{directory_d}/{prefix}.csv"

解释

这是一个Python字符串格式化的例子。在Python中,使用f-string(格式化字符串字面量)可以方便地插入变量的值到字符串中。

f"{directory_d}/{prefix}.csv" 的意思是:

  • {directory_d}:这个位置将被 directory_d 变量的值替代。
  • {prefix}:这个位置将被 prefix 变量的值替代。
  • .csv:这个部分是一个固定的字符串,表示文件的后缀名。

所以,如果 directory_d 的值是 /home/data,而 prefix 的值是 20230917,那么整个字符串的值将是 /home/data/20230917.csv

五、代码段2的解释

代码段2

merged_df = merged_df.loc[:,~merged_df.columns.duplicated()] 

解释

这句代码使用了Pandas库的几个功能来删除重复的列。

  1. merged_df.columns: 返回一个包含DataFrame所有列名的Index对象。
  2. merged_df.columns.duplicated(): 对列名进行判断,返回一个布尔值的Series,其中重复的列名对应的位置为True,不重复的列名对应的位置为False。
  3. ~: 逻辑非操作符。它反转布尔值的Series,所以重复的列名对应的位置变为False,不重复的列名对应的位置变为True。
  4. merged_df.loc[:, ~merged_df.columns.duplicated()]: 使用loc函数选择那些在上述布尔Series中为True的列,即不重复的列。

这句代码的作用是删除merged_df中重复的列。

六、代码段3的解释

代码段3

or file in files:
    if file.endswith('.csv'):
        prefix = file.split('_')[0]
        sorted_files.setdefault(prefix, []).append(file) 

解释

这段代码主要是对一个文件列表进行分类,基于文件名中的特定前缀。

  1. for file in files::这是一个for循环,遍历files列表中的每一个文件名。

  2. if file.endswith('.csv')::检查当前文件名是否以.csv结尾。这通常用来确定一个文件是否为CSV格式。

  3. prefix = file.split('_')[0]:这里使用split方法来分割文件名。假设文件名是prefix_data.csv,那么split('_')会返回一个列表,如['prefix', 'data.csv']。然后通过索引[0]获取第一个元素,即文件名前面的部分(前缀)。

  4. sorted_files.setdefault(prefix, []).append(file)

    • sorted_files是一个字典,用于存储不同前缀的文件列表。
    • setdefault(prefix, []):如果字典中已经有了键prefix,则返回其对应的值(一个列表)。如果字典中没有这个键,则添加一个新键并为其分配一个空列表作为值。
    • .append(file):将当前文件名添加到与前缀对应的列表中。

这段代码的目的是将所有以.csv结尾的文件按照其文件名中的前缀进行分类,并将这些文件存储在sorted_files字典中,其中键是前缀,值是具有相同前缀的文件列表。

七、代码段4的解释

代码段4

for prefix, file_list in sorted_files.items():
    dataframes = []
    for filename in file_list:
        filepath = os.path.join(directory, filename)
        df = pd.read_csv(filepath)
        dataframes.append(df)  

解释

这段代码主要负责读取每个文件并将其内容存储为一个pandas DataFrame,然后将其添加到一个列表中。

  1. for prefix, file_list in sorted_files.items()::这是一个for循环,遍历sorted_files字典中的键值对。其中,prefix是键(前缀),file_list是值(具有相同前缀的文件列表)。
  2. dataframes = []:初始化一个空列表,用于存储每个文件的内容作为一个DataFrame。
  3. for filename in file_list::对于每个文件名,执行以下操作。
  4. filepath = os.path.join(directory, filename):使用os.path.join函数连接目录路径和文件名,得到完整的文件路径。
  5. df = pd.read_csv(filepath):使用pandas的read_csv函数读取CSV文件,并将其内容存储为一个DataFrame。
  6. dataframes.append(df):将这个DataFrame添加到dataframes列表中。

这段代码的目的是读取每个文件的内容,并将其存储为一个DataFrame,然后将这些DataFrame添加到dataframes列表中。

  • 28
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

109702008

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值