我在子目录中有大约20000个文档。我想全部阅读它们,并将它们附加为一个列表列表。到目前为止,这是我的代码,
topics =os.listdir(my_directory)
df =[]
for topic in topics:
files = os.listdir (my_directory+ '/'+ topic)
print(files)
for file in files:
print(file)
f = open(my_directory+ '/'+ topic+ '/'+file, 'r', encoding ='latin1')
data = f.read().replace('\n', ' ')
print(data)
f.close()
df = np.append(df, data)
但是这效率低下,读取它们并将它们附加到df列表中需要花费很长时间。我的预期输出是
df= [[doc1], [doc2], [doc3], [doc4],......,[doc20000]]
我运行了上面的代码,花了6个小时以上,但仍未完成(可能是文档的一半)。如何更改代码以使其更快?
答案 0 :(得分:1)
您只能做很多事情来加快磁盘访问速度。您可以使用线程通过latin1
解码和换行符来重叠某些文件读取操作。但实际上,不会有太大的不同。
import multiprocessing.pool
MEG = 2**20
filelist = []
topics =os.listdir(my_directory)
for topic in topics:
files = os.listdir (my_directory+ '/'+ topic)
print(files)
for file in files:
print(file)
filelist.append(my_directory+ '/'+ topic+ '/'+file)
def worker(filename):
with open(filename, encoding ='latin1', bufsize=1*MEG) as f:
data = f.read().replace('\n', ' ')
#print(data)
return data
with multiprocessing.pool.ThreadPool() as pool:
datalist = pool.map(worker, filelist, chunksize=1)
df = np.array(datalist)
答案 1 :(得分:0)
生成器函数使您可以声明行为类似于 一个迭代器,即可以在for循环中使用。
def read_in_chunks(file, chunk_size=1024):
"""Lazy function (generator) to read a file piece by piece.
Default chunk size: 1k."""
while True:
data = file.read(chunk_size)
if not data:
break
yield data
with open('big_file.dat') as f:
for piece in read_in_chunks(f):
process_data(piece)
class Reader(object):
def __init__(self, g):
self.g = g
def read(self, n=0):
try:
return next(self.g)
except StopIteration:
return ''
df = pd.concat(list(pd.read_csv(Reader(read_in_chunks()),chunksize=10000)),axis=1)
df.to_csv("output.csv", index=False)
答案 2 :(得分:0)
我误读了行df = np.append(df, data)
,并假定您要追加到DataFrame,而不是numpy数组。因此,我的评论有点无关紧要,但我会将其留给其他人,让我像我一样误读或对熊猫的DataFrame追加有类似的问题。
看来您的问题可能无法真正解决您的实际问题。 您是否测量了两个最重要的通话的效果?
files = os.listdir (my_directory+ '/'+ topic)
df = np.append(df, data)
格式化代码的方式使我认为存在一个错误:df = np.append(df, data)
在文件的for循环范围之外,因此我认为只有最后一个data
被附加到数据框。如果这只是帖子中代码格式化的问题,而您确实确实将20k文件追加到数据框中,则可能是问题所在-追加到DataFrame
很慢。
像往常一样,可以通过在问题上投入更多的内存来解决性能下降的问题。如果您有足够的内存来预先加载all
个文件,然后再将其插入DataFrame中,则可能会更快。
关键是在加载所有数据之前不要处理任何熊猫操作。只有这样,您才能使用DataFrame
的{{3}}或其其他工厂方法之一。
一个很好的SO问题,我发现了更多讨论:
from_records
DataFrame
,说DataFrame.from_records