Skip to main content
 首页 » 编程设计

python之组合 CSV 文件集 python

2025年05月04日8TianFang

我有一个包含 2000 个文件的列表,我想合并这些文件:

01-0628-11A-01D-0356-01_hg19 
01-0628-11A-01D-0356-01_hg20 
01-0628-11A-01D-0356-01_hg21 
01-1372-11A-01D-0356-01_hg16 
01-1372-11A-01D-0356-01_hg17 
... 


我已经将文件放入一个 glob 中,并使用正则表达式将文件重命名为公共(public)标识符(如下所示的六位代码),但是每个标识符都有不同数量的原始文件。

01-0628 
01-0628 
01-0628 
01-1372 
01-1372 
... 

我原本打算只使用一个阅读器并打开每个具有通用名称的文件,但我想知道是否有更有效的方法来做到这一点。

我想要的最终输出如下,每个具有公共(public)标识符的文件合并为一个:

01-0628 
01-1372 
... 

所有文件都包含类似格式的数据,因此简单地将现有文件附加到新文件不会有问题。

请您参考如下方法:

假设这些 csvs 具有相似或相同的字段。这段代码应该可以工作。它使用 csv 模块的 DictReader 和 DictWriter 类将 csv 行转换为 Python 字典。

1) 它打开 globbed csv 文件并将其从 in_csv_dir 读入(文件名,行)字典。

2) 它根据文件名和 prefix_length 变量将 csv 行分组到一个(前缀,行)字典中。

3) 它结合了每个前缀分组的字段,并在 out_csv_dir 中创建了一个组合的 csv。

4) 由于字典键是无序的,您的 csvs 可能具有特定的字段顺序。这可以输入到 field_order 中。这将对 csv 字段进行排序,但不会对未在 field_order 中定义的字段失败。

import os 
import sys 
 
# Import System libraries 
from csv import DictReader, DictWriter 
import glob 
 
in_csv_dir = ".\\csvs" 
out_csv_dir = ".\\combined_csvs" 
prefix_length = 2 
 
field_order = ["NAME", "TITLE", "COMPANY", "LOCATION"] 
field_check = lambda q: field_order.index(q) if(field_order.count(q)) else sys.maxint 
csvs = {} 
gotten_files = glob.glob(os.path.join(in_csv_dir, "*.csv")) 
for glob_filename in gotten_files: 
    print "%-11s%s" % ("Opening:", glob_filename) 
    file_obj = open(glob_filename, "rb") 
    cur_reader = DictReader(file_obj) 
    cur_record = [q for q in cur_reader.__iter__()] 
    file_obj.close() 
    if(cur_record): 
        (path, filename_ext) = os.path.split(glob_filename) 
        (filename, ext) = os.path.splitext(filename_ext) 
        csvs[filename] = cur_record 
 
csv_prefixes = list(set([x[:prefix_length] for x in csvs.keys()])) 
csv_groups = dict([(prefix, []) for prefix in csv_prefixes]) 
map(lambda (key, value): csv_groups[key[:prefix_length]].extend(value), csvs.items()) 
 
for (key, sub_csvs) in csv_groups.items(): 
    com_keys = list(reduce(lambda x, y: x|set(y.keys()), sub_csvs, set([]))) 
    com_keys.sort(cmp=lambda x, y: field_check(x) - field_check(y)) 
 
    filename = os.path.join(out_csv_dir, "%s.csv" % key) 
    print "%-11s%s" % ("Combining:", filename) 
    file_obj = open(filename, "wb") 
    temp_csv = DictWriter(file_obj, com_keys) 
 
    temp_csv.writerow(dict(zip(com_keys, com_keys))) 
    map(lambda x: temp_csv.writerow(x), sub_csvs) 
    file_obj.close()