统计 / 大数据集的分布
在讨论如何从数据文件中进行简单统计时,我在想,哪些方法在处理非常大的数据集(比如有几百万条记录,几GB的数据)时效果最好。
使用numpy的解决方案,把整个数据集都读入内存,这样做合适吗?可以参考这个链接:
1 个回答
1
你没有说明你手里有什么数据,以及你想要计算什么!
如果你有一些数据,或者这些数据可以很容易地转换成适中的正整数(比如0到1亿之间的数),你可以使用 bincount
。下面是一个例子,展示如何对一个非常大的文件中的所有字节值制作分布图(直方图),这个方法可以处理你文件系统能管理的任何大小:
import numpy as np
# number of bytes to read at a time
CHUNKSIZE = 100000000
# open the file
f = open("myfile.dat", "rb")
# cumulative distribution array
cum = np.zeros(256)
# read through the file chunk by chunk
while True:
chunkdata = np.fromstring(f.read(CHUNKSIZE), dtype='uint8')
cum += np.bincount(chunkdata)
if len(chunkdata < CHUNKSIZE):
break
这个方法非常快,速度主要受磁盘访问的限制。(我在操作系统缓存中用一个文件测试时,速度大约是每秒1GB。)
当然,你可能还想计算其他统计数据(比如标准差等),但即使这样,你通常也可以用分布图(直方图)来计算这些统计数据。不过,如果你不需要分布图,那可能还有更快的方法。计算平均值其实就是把所有值加在一起。
如果你有一个文本文件,那么主要的挑战就是逐块解析这个文件。标准的方法 loadtxt
和 csv
模块在处理非常大的文件时不一定高效。
如果你有浮点数或者非常大的整数,上面的方法就不能直接使用,但在某些情况下,你可以只用浮点数的一部分,或者把它们四舍五入成最接近的整数等等。总之,问题的关键在于你到底有什么数据,以及你想计算什么统计数据。没有一种“瑞士军刀”能解决所有大文件的统计问题。
如果你的内存足够,把数据读入内存是一个很好的选择。在某些情况下,即使内存不够,你也可以做到这一点(使用 numpy.memmap
)。如果你有一个包含1GB浮点数的文本文件,最终结果可能会小于1GB,而且大多数计算机都能很好地处理这个。只要确保你使用的是64位的Python。