[英]Python merging multiple files to single csv file efficient
我有一組文件,想要將它們合並到一個CSV文件(一個矩陣)。 弼,有一些問題。
在每個文件中都是應該在矩陣中獲得值1的列的名稱。 例:
#File Alpha
dog
house
car
#File Beta
dog
cat
#resulting matrix
,dog,house,car,cat
Alpha,1,1,1,0
Beta,1,0,0,1
經過一番研究后,我提出了以下想法:
import pandas
import os
import shutil
df = pandas.DataFrame()
df['dir'] = 0
directory_0 = os.fsencode("direc0")
for file in os.listdir(directory_0):
filename = os.fsdecode(file)
df.append(pandas.Series( name = filename))
with open("direc10{}".format(filename), "r") as f:
for line in f:
if len(line[:-1]) > 0:
if line[:-1] in df.columns:
df.loc[filename, line[:-1]] = 1
else:
df[line[:-1]] = 0
df.loc[filename, line[:-1]] = 1
df.fillna(0, inplace=True)
df.to_csv("dataset.csv")
一些評論
問題這段代碼完成了工作,但需要一種方法來解決問題。
#Runtime for the above code
500 files after 17 seconds
1,000 files after 50 seconds
1,500 files after 111 seconds
2,000 files after 203 seconds
2,500 files after 324 seconds
3,000 files after 489 seconds
3,500 files after 695 seconds
4,000 files after 960 seconds
有沒有辦法更快地做到這一點(幾個小時內有100,000個文件)?
提前致謝 :)
PS:請原諒我的英語,這不是我的第一語言
100.000行不是那種容易處理CSV文件的大小 - 你會松散很多 - 在SQL數據庫中加入這種數據結構會更有效率。
此外,使效率降低的原因是Pandas搜索列名是線性的,當你得到幾千個單詞時, if line[:-1] in df.columns
中為每個文件行運行的if line[:-1] in df.columns
將開始采用它負擔。
此外,對於~100000個文件,甚至os.listdir
可能會很慢 - pathlib.Path.iterdir
可能會更快。
無論如何,將其構建為Python字典,其中O(1)時間到達鍵將會快得多。 您可以稍后將其轉換為數據幀,或者如果確實需要,可以直接將信息記錄在CSV文件中。
import pathlib
dir1 = pathlib.Path("direc0") # Pathlib will also take care of filesystem filename encodings
data = {}
for filepath in dir1.iterdir():
for line in filepath.open():
line = line.strip()
data.setdefault(line, set()).add(filepath.name)
此時,您將所有數據都存儲在內存中,其中包含單詞作為鍵和一組包含每個單詞作為值的文件名。
要直接編寫CSV文件,此代碼應該足夠 - 因為所有數據都在內存中,並且代碼避免了線性搜索,所以這應該足夠快。 問題是如果數據首先不適合內存。
import csv
from collections import defaultdict
transposed = {}
for key, values in data.items():
for value in values:
transposed.set_default(value, set()).add(key)
with open("dataset.csv", "wt") as file:
writer = csv.writer(file)
headers = list(data.keys())
writer.writerow(["file",] + headers)
for key, values in transposed.items():
writer.writerow([key,] + [int(word in values) for word in headers ])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.