我需要使用numpy对一个非常大的基因组数据集进行排序。我有一个由26亿个浮点数组成的数组,维度为(868940742,3)
,一旦加载并静止,它就占用我的机器上约20GB的内存。我有一台带有16GB RAM,500GB固态硬盘和3.1GHz英特尔i7处理器的2015年早期13寸MacBook Pro。仅仅加载这个数组就会溢出到虚拟内存,但还没有到让我的机器受影响或不得不停止其他正在进行的工作的地步。
我逐步从22个较小的(N,2)
子数组构建了这个非常大的数组。
函数FUN_1
使用每个名为sub_arr
的22个子数组生成2个新的(N,1)
数组。
FUN_1
的第一个输出是通过在b = array([X, F(X)])
数组上插值sub_arr [:,0]
中的值生成的,第二个输出是通过使用r = array([X, BIN(X)])
数组将sub_arr [:,0]
放入箱子中生成的。我分别称这些输出为b_arr
和rate_arr
。该函数返回一个由(N,1)
数组组成的3元组:
import numpy as np
def FUN_1(sub_arr):
"""interpolate b values and rates based on position in sub_arr"""
b = np.load(bfile)
r = np.load(rfile)
b_arr = np.interp(sub_arr[:,0], b[:,0], b[:,1])
rate_arr = np.searchsorted(r[:,0], sub_arr[:,0]) # HUGE efficiency gain over np.digitize...
return r[rate_r, 1], b_arr, sub_arr[:,1]
在for循环中,我调用这个函数22次,并使用值填充一个预先分配的全0数组full_arr = numpy.zeros([868940742, 3])
:
full_arr[:,0], full_arr[:,1], full_arr[:,2] = FUN_1
就节省内存而言,在这个步骤上,我认为这是我能做到的最好的,但我很乐意听取建议。无论如何,直到此时我都没有遇到问题,而且只需要大约2分钟。
以下是排序例程(有两个连续的排序)
for idx in range(2):
sort_idx = numpy.argsort(full_arr[:,idx])
full_arr = full_arr[sort_idx]
# ...
# <additional processing, return small (1000, 3) array of stats>
现在这个排序算法已经在慢慢工作了(需要大约10分钟)。然而,我最近开始在FUN_1
中使用一个更大的、更细密的[X, F(X)]
值表进行插值步骤,以返回b_arr
。现在SORT真的变得很慢,尽管其他一切都保持不变。
有趣的是,在SORT速度变慢的步骤中,我甚至没有对插值后的值进行排序。下面是不同插值文件的一些片段 - 在每种情况下,较小的文件约小30%,在第二列的值方面更加均匀;较慢的文件具有更高的分辨率和更多独特的数据,因此插值结果可能更加独特,但我不确定这是否会产生任何影响...?
较大、较慢的文件:
17399307 99.4
17493652 98.8
17570460 98.2
17575180 97.6
17577127 97
17578255 96.4
17580576 95.8
17583028 95.2
17583699 94.6
17584172 94
更小、更均匀的常规文件:
1 24
1001 24
2001 24
3001 24
4001 24
5001 24
6001 24
7001 24
我不确定是什么原因导致了这个问题,我很乐意听取任何关于在这种内存限制情况下进行排序的建议或一般性的意见!