我需要使用 numpy 对非常大的基因组数据集进行排序。我有一个 26 亿个浮点数的数组,维度 =(868940742, 3)
加载后,它会占用我机器上大约 20GB 的内存。我有一台 2015 年初的 13 英寸 MacBook Pro,配备 16GB RAM、500GB 固态硬盘和 3.1 GHz intel i7 处理器。只是加载数组会溢出到虚拟内存,但不会到我的机器受到影响的程度,或者我必须停止我正在做的所有其他事情。
我从 22 个较小的数组一步步构建这个非常大的数组(N, 2)
子数组。
功能FUN_1
生成 2 个新的(N, 1)
使用我称之为的 22 个子数组中的每一个的数组sub_arr
.
第一个输出为FUN_1
是通过插入值生成的sub_arr[:,0]
在阵列上b = array([X, F(X)])
第二个输出是通过放置生成的sub_arr[:, 0]
使用数组放入 bin 中r = array([X, BIN(X)])
。我称这些输出为b_arr
and rate_arr
, 分别。该函数返回一个 3 元组(N, 1)
arrays:
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 次,并填充预先分配的零数组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 分钟)。然而,我最近开始使用更大、更精细的分辨率表[X, F(X)]
上述插值步骤的值FUN_1
返回b_arr
现在排序确实变慢了,尽管其他一切都保持不变。
有趣的是,我什至没有在排序现在滞后的步骤中对插值进行排序。以下是不同插值文件的一些片段 - 较小的插值文件在每种情况下大约小 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
我不确定是什么导致了这个问题,我对任何建议或关于在这种类型的内存限制情况下进行排序的一般输入感兴趣!