Мне нужно отсортировать ОЧЕНЬ большой геномный набор данных, используя numpy. Я имею массив из 2.6 миллиардов поплавков, размеры = (868940742, 3)
, который занимает примерно 20 ГБ памяти на моей машине после загрузки и просто сидит там. У меня есть ранний планшет "MacBook Pro" на раннем этапе 2015 года с 16 ГБ оперативной памяти, твердотельный HD 500 ГБ и процессор Intel i7 с тактовой частотой 3,1 ГГц. Просто загрузите массив переполнения в виртуальную память, но не до такой степени, что моя машина страдает, или я должен остановить все остальное, что я делаю.
Я строю этот ОЧЕНЬ большой массив шаг за шагом из 22 меньших подкаров (N, 2)
.
Функция FUN_1
генерирует 2 новых массива (N, 1)
, используя каждый из 22 подмассивов, которые я называю sub_arr
.
Первый вывод FUN_1
генерируется путем интерполяции значений из sub_arr[:,0]
в массиве b = array([X, F(X)])
, а второй вывод создается путем размещения sub_arr[:, 0]
в бункеры с использованием массива r = array([X, BIN(X)])
. Я вызываю эти выходы b_arr
и rate_arr
соответственно. Функция возвращает 3-кортеж (N, 1)
массивов:
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]
Я вызываю функцию 22 раза в цикле for и заполняю предварительно выделенный массив нулей 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
, и теперь 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
Я не уверен, что может вызвать эту проблему, и меня бы интересовали любые предложения или просто общий ввод о сортировке в этом типе памяти, ограничивающий регистр!