Быстрое сокращение огромной матрицы с помощью python (numpy memmap, pytables или другие?)

В рамках обработки данных я создаю огромные не разреженные матрицы порядка 100000*100000 ячеек, которые я хочу уменьшить в 10 раз, чтобы уменьшить объем данных. В этом случае я хочу усреднить по блокам 10*10 пикселей, чтобы уменьшить размер моей матрицы с 100000*100000 до 10000*10000.

Какой самый быстрый способ сделать это с помощью Python? Для меня не имеет значения, нужно ли мне сохранять исходные данные в новом формате данных, потому что мне приходится выполнять понижающую дискретизацию одного и того же набора данных несколько раз.

В настоящее время я использую numpy.memmap:

import numpy as np

data_1 = 'data_1.dat'
date_2 = 'data_2.dat'
lines = 100000
pixels = 100000
window = 10

new_lines = lines / window
new_pixels = pixels / window
dat_1 = np.memmap(data_1, dtype='float32', mode='r', shape=(lines, pixels))
dat_2 = np.memmap(data_2, dtype='float32', mode='r', shape=(lines, pixels))

dat_in = dat_1 * dat_2
dat_out = dat_in.reshape([new_lines, window, new_pixels, window]).mean(3).mean(1)

Но с большими файлами этот метод становится очень медленным. Вероятно, это как-то связано с двоичными данными этих файлов, которые упорядочены по строке. Поэтому я думаю, что формат данных, в котором мои данные будут храниться в блоках, а не в строках, будет быстрее, но я не уверен, каким будет прирост производительности и существуют ли пакеты Python, которые поддерживают это.

Я также думал о понижающей дискретизации данных до создания такой огромной матрицы (здесь не показана), но мои входные данные разбиты и нерегулярны, так что это станет очень сложным.

2 ответа

Решение

Исходя из этого ответа, я думаю, что это может быть относительно быстрый метод, в зависимости от того, сколько накладных расходов reshape дает вам с memmap,

def downSample(a, window):
     i, j = a.shape
     ir = np.arange(0, i, window)
     jr = np.arange(0, j, window)
     n = 1./(window**2)
     return n * np.add.reduceat(np.add.reduceat(a, ir), jr, axis=1)

Трудно проверить скорость без вашего набора данных.

Это позволяет избежать промежуточной копии, так как изменение формы сохраняет размеры непрерывными

dat_in.reshape((lines/window, window, pixels/window, window)).mean(axis=(1,3))
Другие вопросы по тегам