【问题标题】:Python: write CSV with matching data from multiple CSV filesPython:使用来自多个 CSV 文件的匹配数据写入 CSV
【发布时间】:2017-06-02 11:25:03
【问题描述】:

我需要匹配来自多个 CSV 文件的数据。我编写了一个处理简单数据的脚本,但是分析 4000 行的速度很慢。 我已经尝试过set(a) & set(b),但无法从每个文件中返回匹配数据。 输出文件必须具有来自所有文件的匹配数据。

脚本:

    for file_1 in files:
        with open(file_1, 'rt') as f1,open(saved_file, 'w') as f3:
            reader1 = csv.reader(f1, delimiter = ';')
            writer = csv.writer(f3, delimiter = ';', lineterminator = '\n')

            for row1 in reader1:
                for row1 in reader1:
                    for file_2 in files:
                        with open(file_2, 'rt') as f2:
                            reader2 = csv.reader(f2, delimiter = ';')
                            if row1 in reader2:
                                writer.writerow(row1)

我尝试匹配的数据如下所示:

文件_1:

May 22, 2017;12,615.50;12,650.50;12,665.00;12,567.00;-;-0.18%
May 19, 2017;12,638.69;12,612.30;12,658.55;12,596.72;121.95M;0.39%
May 18, 2017;12,590.06;12,608.19;12,634.26;12,489.95;123.48M;-0.33%
May 17, 2017;12,631.61;12,700.12;12,786.89;12,587.45;108.95M;-1.35%
May 15, 2017;12,807.04;12,824.05;12,832.29;12,729.49;87.08M;0.29%

文件_2:

May 22, 2017;1.1238;1.1200;1.1265;1.1160;0.28%
May 19, 2017;1.1207;1.1100;1.1214;1.1094;0.94%
May 17, 2017;1.1159;1.1082;1.1163;1.1078;0.69%
May 16, 2017;1.1082;1.0975;1.1098;1.0971;0.97%
May 15, 2017;1.0975;1.0924;1.0991;1.0920;0.40%

输出: 保存文件_1:

May 22, 2017;12,615.50;12,650.50;12,665.00;12,567.00;-;-0.18%
May 19, 2017;12,638.69;12,612.30;12,658.55;12,596.72;121.95M;0.39%
May 17, 2017;12,631.61;12,700.12;12,786.89;12,587.45;108.95M;-1.35%
May 15, 2017;12,807.04;12,824.05;12,832.29;12,729.49;87.08M;0.29%

保存文件_2:

May 22, 2017;1.1238;1.1200;1.1265;1.1160;0.28%
May 19, 2017;1.1207;1.1100;1.1214;1.1094;0.94%
May 17, 2017;1.1159;1.1082;1.1163;1.1078;0.69%
May 15, 2017;1.0975;1.0924;1.0991;1.0920;0.40%

【问题讨论】:

    标签: python csv data-analysis


    【解决方案1】:

    无需借助 Pandas,您就可以做到这一点,这可能与您的想法一致。

    首先浏览每个文件,只在单独的列表中收集日期。然后找到这些列表的交集,将其视为集合。现在再次遍历每个文件,写出日期在交集中的每条记录。

    def get_dates(one_file):
        one_file_dates = []
        with open(one_file) as the_file:
            for line in the_file.readlines():
                the_date = line[:line.find(';')]
                if not the_date in one_file_dates:
                    one_file_dates.append(the_date) 
        return one_file_dates
    
    common_dates = set(get_dates('file_1.csv')).intersection(set(get_dates('file_2.csv')))
    
    print ('*** processing file_1')
    with open('file_1.csv') as the_file:
        for line in the_file.readlines():
            if line[:line.find(';')] in common_dates:
                print(line.strip())
    
    print ('*** processing file_2')
    with open('file_2.csv') as the_file:
        for line in the_file.readlines():
            if line[:line.find(';')] in common_dates:
                print(line.strip())
    

    结果:

    *** processing file_1
    May 22, 2017;12,615.50;12,650.50;12,665.00;12,567.00;-;-0.18%
    May 19, 2017;12,638.69;12,612.30;12,658.55;12,596.72;121.95M;0.39%
    May 17, 2017;12,631.61;12,700.12;12,786.89;12,587.45;108.95M;-1.35%
    May 15, 2017;12,807.04;12,824.05;12,832.29;12,729.49;87.08M;0.29%
    *** processing file_2
    May 22, 2017;1.1238;1.1200;1.1265;1.1160;0.28%
    May 19, 2017;1.1207;1.1100;1.1214;1.1094;0.94%
    May 17, 2017;1.1159;1.1082;1.1163;1.1078;0.69%
    May 15, 2017;1.0975;1.0924;1.0991;1.0920;0.40%
    

    编辑:响应评论的新代码。

    def get_dates(one_file):
        one_file_dates = []
        with open(one_file) as the_file:
            for line in the_file.readlines():
                the_date = line[:line.find(';')]
                if not the_date in one_file_dates:
                    one_file_dates.append(the_date) 
        return one_file_dates
    
    file_list = ['file_1.csv', 'file_2.csv'] # add more file names here
    
    common_dates = set(get_dates(file_list[0]))
    for file in file_list[1:]:
        common_dates = common_dates.intersection(set(get_dates(file)))
    
    for file in file_list:
        print ('*** processing ', file)
        with open(file) as the_file:
            for line in the_file.readlines():
                if line[:line.find(';')] in common_dates:
                    print(line.strip())
    

    【讨论】:

    • 它适用于 2 个文件,但我需要在文件列表中搜索并匹配每个文件。
    【解决方案2】:

    性能问题是因为您在 for 循环中使用多个文件读取器/写入器。

    我建议您首先使用 Pandas 将 File_1 和 File_2 中的数据导入数据框中。你可以这样做:

    import pandas as pd 
    df1=pd.read_csv("file_1.csv") 
    df2=pd.read_csv("file_2.csv")
    

    然后您可以将您的计算应用于导入的数据,然后您可以再次将它们保存到 CSV,如下所示:

    dfOut.to_csv(file_name, sep='\t')
    

    您需要在此处处理正确的 CSV 分隔符。

    【讨论】:

    • 读取文件真的很快。如何比较两个文件中的行并将行保存到 csv 文件?
    猜你喜欢
    • 1970-01-01
    • 2019-12-10
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 2021-06-13
    • 2015-01-21
    • 2014-12-29
    • 2021-03-15
    相关资源
    最近更新 更多