我有一个非常大的文本文件(大约80G)。文件只包含数字(整数+浮点数),有20列。现在我要分析每一列。通过分析,我的意思是,我必须对每一列做一些基本的计算,比如找到平均值,绘制直方图,检查条件是否满足等等。我正在读取如下文件
with open(filename) as original_file:
all_rows = [[float(digit) for digit in line.split()] for line in original_file]
all_rows = np.asarray(all_rows)
在此之后,我对特定列进行所有分析。我使用"良好"配置服务器/工作站(32GB RAM)来执行我的程序。问题是我不能完成我的工作。我几乎等了一天才完成这个程序,但它在1天后仍在运行。后来我不得不手动杀死它。我知道我的脚本是正确的,没有任何错误,因为我在较小的文件(约1G)上尝试了相同的脚本,它工作得很好。
我最初的猜测是它会有一些内存问题。我能做这样的工作吗?用不同的方法还是其他方法?
我尝试将文件分割成更小的文件大小,然后在循环中分别分析它们,如下所示
pre_name = "split_file"
for k in range(11): #There are 10 files with almost 8G each
filename = pre_name+str(k).zfill(3) #My files are in form "split_file000, split_file001 ..."
with open(filename) as original_file:
all_rows = [[float(digit) for digit in line.split()] for line in original_file]
all_rows = np.asarray(all_rows)
#Some analysis here
plt.hist(all_rows[:,8],100) #Plotting histogram for 9th Column
all_rows = None
我在一堆较小的文件上测试了上面的代码,它工作得很好。然而,当我在大文件上使用时,又出现了同样的问题。有什么建议吗?还有其他更简洁的方法吗?
对于这种冗长的操作(当数据不适合内存时),使用像dask (http://dask.pydata.org/en/latest/)这样的库可能是有用的,特别是dask.dataframe.read_csv
来读取数据,然后执行您的操作,就像您在pandas库(另一个要提到的有用包)中所做的那样。
我想到了两个选择:
-
您应该考虑使用在线算法执行计算
在计算机科学中,在线算法是一种能够以串行方式逐个处理输入的算法,即按照输入到算法的顺序,而不需要从一开始就提供整个输入。
可以用这种方法以恒定的内存复杂度计算均值和方差以及具有预先指定的bin的直方图。
-
您应该将您的数据放入适当的数据库中,并利用该数据库系统的统计和数据处理能力,例如,聚合函数和索引。
随机链接:- http://www.postgresql.org/
- https://www.mongodb.org/