如何快速合并特定列上的多个 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
我有大约 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