有一个文件目录,目录下有类似下列文件名: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文件。以下是代码的详细解释:
导入必要的库:
os
: 用于与操作系统交互,例如读取目录内容。pandas as pd
: 用于数据处理和分析的库,特别是DataFrame操作。定义目标目录:
directory = "/home/test/tdx_datas_min"
: 这是源目录,其中包含要合并的CSV文件。directory_d = "/home/test/d"
: 这是目标目录,合并后的CSV文件将保存在这里。获取目录中的文件列表:
files = os.listdir(directory)
: 使用os.listdir
函数获取directory
目录下的所有文件名。基于数字前缀对文件进行分类:
.csv
结尾,则使用_
作为分隔符获取文件名的第一个部分(数字前缀),并将该文件添加到具有相同前缀的列表中。合并具有相同前缀的文件:
pd.concat
函数按列(axis=1
)合并这些数据框。这意味着它将尝试将具有相同列名的列合并在一起。merged_df.loc[:,~merged_df.columns.duplicated()]
处理可能存在的重复列名,删除重复的列。保存合并后的文件:
输出信息:
注意事项:
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
。
merged_df = merged_df.loc[:,~merged_df.columns.duplicated()]
这句代码使用了Pandas库的几个功能来删除重复的列。
merged_df.columns
: 返回一个包含DataFrame所有列名的Index对象。merged_df.columns.duplicated()
: 对列名进行判断,返回一个布尔值的Series,其中重复的列名对应的位置为True,不重复的列名对应的位置为False。~
: 逻辑非操作符。它反转布尔值的Series,所以重复的列名对应的位置变为False,不重复的列名对应的位置变为True。merged_df.loc[:, ~merged_df.columns.duplicated()]
: 使用loc函数选择那些在上述布尔Series中为True的列,即不重复的列。这句代码的作用是删除merged_df
中重复的列。
or file in files:
if file.endswith('.csv'):
prefix = file.split('_')[0]
sorted_files.setdefault(prefix, []).append(file)
这段代码主要是对一个文件列表进行分类,基于文件名中的特定前缀。
for file in files:
:这是一个for循环,遍历files
列表中的每一个文件名。
if file.endswith('.csv'):
:检查当前文件名是否以.csv
结尾。这通常用来确定一个文件是否为CSV格式。
prefix = file.split('_')[0]
:这里使用split
方法来分割文件名。假设文件名是prefix_data.csv
,那么split('_')
会返回一个列表,如['prefix', 'data.csv']
。然后通过索引[0]
获取第一个元素,即文件名前面的部分(前缀)。
sorted_files.setdefault(prefix, []).append(file)
:
sorted_files
是一个字典,用于存储不同前缀的文件列表。setdefault(prefix, [])
:如果字典中已经有了键prefix
,则返回其对应的值(一个列表)。如果字典中没有这个键,则添加一个新键并为其分配一个空列表作为值。.append(file)
:将当前文件名添加到与前缀对应的列表中。这段代码的目的是将所有以.csv
结尾的文件按照其文件名中的前缀进行分类,并将这些文件存储在sorted_files
字典中,其中键是前缀,值是具有相同前缀的文件列表。
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,然后将其添加到一个列表中。
for prefix, file_list in sorted_files.items():
:这是一个for循环,遍历sorted_files
字典中的键值对。其中,prefix
是键(前缀),file_list
是值(具有相同前缀的文件列表)。dataframes = []
:初始化一个空列表,用于存储每个文件的内容作为一个DataFrame。for filename in file_list:
:对于每个文件名,执行以下操作。filepath = os.path.join(directory, filename)
:使用os.path.join
函数连接目录路径和文件名,得到完整的文件路径。df = pd.read_csv(filepath)
:使用pandas的read_csv
函数读取CSV文件,并将其内容存储为一个DataFrame。dataframes.append(df)
:将这个DataFrame添加到dataframes
列表中。这段代码的目的是读取每个文件的内容,并将其存储为一个DataFrame,然后将这些DataFrame添加到dataframes
列表中。