Я хотел бы рассчитать SVD из большой матрицы на Dask . Тем не менее, я наивно пытался создать пустой 2D-массив и обновить его в al oop, но Dask не позволяет изменять массив. Итак, я ищу обходной путь. Я пытался сохранить большой (около 65 000 x 65 000 или даже больше) массив в HDF5 с помощью h5py
, но обновление массива в al oop довольно неэффективно. Должен ли я использовать mmap
с отображением памяти numpy вместо?
Ниже я поделился примером кода без какой-либо реализации dask. Должен ли я использовать dask.bag
или dask.delayed
для этой операции?
Пример кода принимает длинные строки и размер окна 8, генерирует комбинации из двухбуквенных слов. В реальных данных размер окна будет 20, а слова будут длиной 8 букв. И длина входной строки может составлять 3 Гб.
import itertools
import numpy as np
np.set_printoptions(threshold=np.Inf)
# generate all possible words of length 2 (AA, AC, AG, AT, CA, etc.)
# then get numerical index (AA -> 0, AC -> 1, etc.)
bases=['A','C','G','T']
all_two = [''.join(p) for p in itertools.product(bases, repeat=2)]
two_index = {x: y for (x,y) in zip(all_two, range(len(all_two)))}
# final array to fill, size is [ 16 possible words x 16 possible words ]
counts = np.zeros(shape=(16,16)) # in actual sample we expect 65000x65000 array
# sample sequences (these will be gigabytes long in actual sample)
seq1 = "AAAAACCATCGACTACGACTAC"
seq2 = "ACGATCACGACTACGACTAGATGCATCACGACTAAAAA"
# accumulate results
all_pairs=[]
def generate_pairs(sequence):
pairs=[]
for i in range(len(sequence)-8+1):
window=sequence[i:i+8]
words= [window[i:i+2] for i in range(0, len(window), 2)]
for pair in itertools.combinations(words,2):
pairs.append(pair)
return pairs
# use function for each sequence
all_pairs.extend(generate_pairs(seq1))
all_pairs.extend(generate_pairs(seq2))
# convert 1D array of pairs into 2D counts of pairs
# for each pair, lookup word index and increase corresponding cell
for j in all_pairs:
counts[ two_index[j[0]], two_index[j[1]] ] += 1
print(counts)
РЕДАКТИРОВАТЬ: Я мог бы задать вопрос немного сложнее, позвольте мне перефразировать его. Мне нужно построить один большой 2D-массив размером ~ 65000x65000. Массив должен быть заполнен подсчетом вхождений пар (word1,word2)
. Поскольку Dask не разрешает назначение / изменение элемента для массива Dask, я не могу заполнить массив, поскольку пары обрабатываются. Есть ли обходной путь для создания / заполнения большого 2D-массива с помощью Dask?
Вот более простой код для тестирования:
import itertools
import numpy as np
np.set_printoptions(threshold=np.Inf)
bases=['A','C','G','T']
all_two = [''.join(p) for p in itertools.product(bases, repeat=2)]
two_index = {x: y for (x,y) in zip(all_two, range(len(all_two)))}
seq = "AAAAACCATCGACTACGACTAC"
counts = np.zeros(shape=(16,16))
for i in range(len(seq)-8+1):
window=seq[i:i+8]
words= [window[i:i+2] for i in range(0, len(window), 2)]
for pair in itertools.combinations(words,2):
counts[two_index[pair[0]], two_index[pair[1]]] += 1 # problematic part!
print(counts)