Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 总结大量数据_Python_Python 3.x_Nlp_Hdf5_Large Data - Fatal编程技术网

Python 总结大量数据

Python 总结大量数据,python,python-3.x,nlp,hdf5,large-data,Python,Python 3.x,Nlp,Hdf5,Large Data,我有一个无法解决的问题。我有4个.txt文件,每个文件的大小在30-70GB之间。每个文件包含n-gram条目,如下所示: blabla1/blabla2/blabla3 word1/word2/word3 ... 我想做的是计算每个项目出现的次数,并将这些数据保存到新文件中,例如: blabla1/blabla2/blabla3 : 1 word1/word2/word3 : 3 ... 到目前为止,我的尝试只是将所有条目保存在一本字典中,并对它们进行计数,即 entry_

我有一个无法解决的问题。我有4个
.txt
文件,每个文件的大小在30-70GB之间。每个文件包含n-gram条目,如下所示:

blabla1/blabla2/blabla3
word1/word2/word3
...
我想做的是计算每个项目出现的次数,并将这些数据保存到新文件中,例如:

blabla1/blabla2/blabla3  : 1
word1/word2/word3        : 3
...
到目前为止,我的尝试只是将所有条目保存在一本字典中,并对它们进行计数,即

entry_count_dict = defaultdict(int)
with open(file) as f:
    for line in f:
        entry_count_dict[line] += 1
然而,使用这种方法我会遇到内存错误(我有8GB的RAM可用)。数据遵循齐普夫分布,例如,大多数项目仅出现一次或两次。 参赛作品的总数尚不清楚,但(非常)粗略的估计是,参赛作品总数约为15000000件

除此之外,我还尝试了
h5py
,将所有条目保存为一个包含数组
[1]
的h5py数据集,然后更新该数组,例如:

import h5py
import numpy as np

entry_count_dict = h5py.File(filename)
with open(file) as f:
    for line in f:
        if line in entry_count_dict:
            entry_count_file[line][0] += 1
        else:
            entry_count_file.create_dataset(line, 
                                            data=np.array([1]),
                                            compression="lzf")
然而,这种方法是缓慢的。书写速度越来越慢。因此,除非可以提高写入速度,否则这种方法是不可信的。此外,在块中处理数据和打开/关闭每个块的h5py文件在处理速度上没有显示任何显著差异

我一直在考虑将以某些字母开头的条目保存在单独的文件中,即所有以
a
开头的条目都保存在
a.txt
中,依此类推(这应该可以使用
defaultdic(int)
)。 然而,要做到这一点,该文件必须对每个字母迭代一次,这在给定文件大小(max=69GB)的情况下是不可信的。 也许在迭代文件时,可以打开pickle并将条目保存在dict中,然后关闭pickle。但是,由于打开、加载和关闭pickle文件所需的时间,对每个项目执行此操作会大大降低过程的速度

解决这个问题的一种方法是在一次过程中对所有条目进行排序,然后迭代排序后的文件并按字母顺序对条目进行计数。但是,即使使用linux命令对文件进行排序也非常缓慢:

sort file.txt>sorted_file.txt

而且,我真的不知道如何使用python解决这个问题,因为将整个文件加载到内存中进行排序会导致内存错误。我对不同的排序算法有一些肤浅的了解,但是它们似乎都需要将要排序的整个对象加载到内存中


任何关于如何实现这一点的建议都将不胜感激

有许多算法可用于执行这种类型的操作。它们都属于一般的标题

“将以某些字母开头的条目保存在单独的文件中”实际上被称为bucket sort,理论上应该更快。尝试使用切片数据集

或者, try是一个由DARPA+Anaconda支持的分布式计算库,具有numpy、pandas所熟悉的接口,其工作原理类似于ApacheSpark。(也适用于单机) 顺便说一句,它的规模

我建议尝试dask.array, 它将大型阵列切割为许多小型阵列,并使用阻塞算法实现numpy ndarray接口,以在计算这些大于内存的数据时利用所有核心

我一直在考虑将以某些字母开头的条目保存在单独的文件中,即所有以a开头的条目都保存在a.txt中,等等(这应该可以使用defaultdic(int)实现)。然而,要做到这一点,该文件必须对每个字母迭代一次,这在给定文件大小(max=69GB)的情况下是不可信的

你的这一思路就快到了。您要做的是根据前缀分割文件-不必对每个字母迭代一次。这在awk中是微不足道的。假设您的输入文件位于名为
input
的目录中:

mkdir output
awk '/./ {print $0 > ( "output/"  substr($0,0,1))}` input/*
这将把每一行附加到一个以该行的第一个字符命名的文件中(注意,如果您的行可以以空格开头,这将很奇怪;因为这些都是ngram,我认为这不相关)。您也可以在Python中执行此操作,但是管理文件的打开和关闭有些繁琐

由于文件已被拆分,它们现在应该小得多。您可以对它们进行排序,但实际上没有必要-您可以单独读取文件,并使用如下代码获取计数:

from collections import Counter

ngrams = Counter()
for line in open(filename):
    ngrams[line.strip()] += 1
for key, val in ngrams.items():
    print(key, val, sep='\t')

如果文件仍然太大,您可以增加用于存储行的前缀的长度,直到文件足够小。

我认为您提出的任何Python解决方案都不会比
sort ngrams.txt | uniq-c
更快,因此,请坚持使用python中的几个模块,它们可以用来实现字典,将条目保存或缓存在磁盘上,而不是内存中。例如,请看。也考虑和寻找一些适合你的需要,即在内存中做大部分工作,只要它适合内存,但是当你的字典“大”到内存中时,使用磁盘。