2017-02-13 21 views
1

У меня есть большая разреженная матрица, содержащая гистограмму, которую я хотел бы построить в качестве тепловой карты. Обычно я бы просто построить полную матрицу (h) следующим образом:Графическая карта разреженной матрицы

import matplotlib.pyplot as plt 
plt.imshow(h.T, interpolation="nearest", origin="lower") 
plt.colorbar() 
plt.savefig("corr.eps") 

В этом случае я, однако есть проблема, что полная матрица будет иметь размеры 189,940x189,940, который является слишком большой для меня, чтобы держать в памяти. Я нашел сообщения о построении шаблона разреженности (например, python matplotlib plot sparse matrix pattern), но ничего о том, как построить схему нагрева еще не превратив ее в плотную матрицу. Можно ли это сделать? (Или есть какой-то другой способ построения графика без исчерпания ОЗУ?) Моя разреженная матрица в настоящее время является lilmatrix (scipy.sparse.lil_matrix).

+0

Никогда не пробовал самостоятельно, но вы заглянули в 'datashader'. Может быть полезно. – reptilicus

+0

Вы считали, что просто очерчиваете точки отдельно, как коллекцию разброса или прямоугольника? – ImportanceOfBeingErnest

+0

Обычно я это делаю, но в этом случае каждая ячейка содержит счетчик, поэтому мне не важно, заполняется ли ячейка, но о том, какое значение она имеет. Я не уверен, как бы я визуализировал это, используя разброс. Я еще не смотрел на 'datashader', но посмотрю. –

ответ

1

Одна из идей заключалась бы в том, чтобы уменьшить использование с использованием разреженных операций.

data = data.tocsc()  # sparse operations are more efficient on csc 
N, M = data.shape 
s, t = 400, 400   # decimation factors for y and x directions 
T = sparse.csc_matrix((np.ones((M,)), np.arange(M), np.r_[np.arange(0, M, t), M]), (M, (M-1) // t + 1)) 
S = sparse.csr_matrix((np.ones((N,)), np.arange(N), np.r_[np.arange(0, N, s), N]), ((N-1) // s + 1, N)) 
result = S @ data @ T  # downsample by binning into s x t rectangles 
result = result.todense() # ready for plotting 

Этот фрагмент кода реализует простой биннинга, но может быть уточнена, чтобы включить более сложные фильтры. Матрицы биннинга представляют собой только двоичные матрицы id, например S_ij = 1, если j // s = i еще 0.

Еще несколько объяснений. Поскольку исходная матрица очень велика, есть возможность уменьшить ее, без какой-либо визуально заметной разницы в выходе.

Вопрос в том, как уменьшить размер без предварительного создания плотного представления. Один из возможных ответов - выразить биннинг в терминах матричного умножения, а затем использовать разреженное матричное умножение.

Так что, если умножив исходные данные справа с матрицей биннинга T затем столбцы T соответствуют закромам столбцов, в частности, число столбцов T определяют, сколько пикселей пониженной дискретизации данных будут иметь в x направление. Каждый столбец T определяет, что входит в соответствующий ящик, а что нет. В примере я установил ряд элементов, которые кодируют соседние столбцы (исходной матрицы) в 1, а остальные - в 0. Это заставляет эти столбцы суммировать их и помещает сумму в матрицу результатов, другими словами, она объединяет эти столбцы вместе ,

Умножение налево работает точно так же, только оно влияет на строки, а не на столбцы.

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

+0

Благодарим вас за предложение. Не могли бы вы объяснить немного больше, как здесь работает выборка/как я меняю то, что отбирается? Боюсь, я еще не совсем это понимаю. –

+0

Я пытался. Посмотрите обновленный пост. –

+0

Я использую python2.7 (извините, что не было видно из моего сообщения), поэтому оператор '@' не существует. Согласно этому сообщению (https://stackoverflow.com/questions/34142485/difference-between-numpy-dot-and-python-3-5-matrix-multiplication) это эквивалент 'np.matmul' в отличие от 'np.dot'. Это то, что вы намеревались? –