如何快速合并特定列上的多个 csv 文件?

How to combine multiple csv files on specific columns in a fast way?

我有大约 200 个 CSV 文件,我需要将它们合并到特定的列中。每个 CSV 文件在特定列上包含 1000 个填充行。我的文件名如下:

csv_files = [en_tr_translated0.csv, en_tr_translated1000.csv, en_tr_translated2000.csv, ......... , en_tr_translated200000.csv]

我的 csv 文件列如下所示:

前两列在所有 csv 文件中预填充了相同的 200.000 rows/sentences。我的每个 en_tr_translated{ }.csv 文件包含 1000 个与其文件名相关的翻译句子。例如: en_tr_translated1000.csv 文件包含第 0 行到第 1000 行的翻译句子,en_tr_translated2000.csv 文件包含第 1000 行到第 2000 行的翻译句子等。其余为 nan/empty。下面是来自 en_tr_translated3000.csv 文件的示例图像。

我想 copy/merge/join 将这些行包含一个完整的 csv 文件,其中包含所有翻译的句子。我尝试了以下代码:

out = pd.read_csv(path + 'en_tr_translated0.csv', sep='\t', names=['en_sentence', 'tr_sentence', 'translated_tr_sentence', 'translated_en_sentence'], dtype=str, encoding='utf-8', low_memory=False)
##
i = 1000

for _ in tqdm(range(200000)):
    new = pd.read_csv(path + f'en_tr_translated{i}.csv', sep='\t', names=['en_sentence', 'tr_sentence', 'translated_tr_sentence', 'translated_en_sentence'], dtype=str, encoding='utf-8', low_memory=False)
    out.loc[_, 'translated_tr_sentence'] = new.loc[_, 'translated_tr_sentence']
    out.loc[_, 'translated_en_sentence'] = new.loc[_, 'translated_en_sentence']
    if _ == i:
        i += 1000

实际上,它工作正常,但我的问题是,它需要 105 小时!!

有没有更快的方法来做到这一点?我必须对 5 个不同的数据集执行此操作,这变得非常烦人。

欢迎任何建议。

我会加载所有文件,删除未完全填充的行,然后连接所有数据帧。

类似于:

dfs = []
for ff in Path('.').rglob('*.csv'):
    dfs.append((pd.read_csv(ff, names=['en_sentence', 'tr_sentence', 'translated_tr_sentence', 'translated_en_sentence'], dtype=str, encoding='utf-8', low_memory=True).dropna())
df = pd.concat(dfs)

您的输入文件中有一行数据与文件中的一行完全相同,对吗?因此,如果您甚至不使用 pandas,它可能会更快。尽管如果正确完成,200.000 应该仍然非常快,无论是否使用 pandas。

不这样做:只需打开每个文件,移动到合适的索引,将 1000 行写入输出文件。然后转到下一个文件。您可能需要修复 headers 等,并注意索引没有变化,但这里有一个如何做到这一点的想法:

with open(path + 'en_tr_translated_combined.csv', 'w') as f_out: # open out file in write modus
    for filename_index in tqdm(range(0, 201000, 1000)): # iterate over each index in steps of 1000 between 0 and 200000
        with open(path + f'en_tr_translated{filename_index}.csv') as f_in: # open file with that index
            for row_index, line in enumerate(f_in): # iterate over its rows
                if row_index < filename_index: # skip rows until you reached the ones with content in translation
                    continue
                if row_index > filename_index + 1000: # close the file if you reached the part where the translations end
                    break
                f_out.write(line) # for the inbetween: copy the content to out file