2014-10-07 3 views
2

Мне нужно итеративно построить огромную разреженную матрицу в numpy/scipy. Intitialization выполняется в цикле:Огромная разреженная матрица в python

from scipy.sparse import dok_matrix, csr_matrix 

def foo(*args): 
    dim_x = 256*256*1024 
    dim_y = 128*128*512 
    matrix = dok_matrix((dim_x, dim_y))  

    for i in range(dim_x): 
     # compute stuff in order to get j 
     matrix[i, j] = 1. 
    return matrix.tocsr() 

Тогда мне нужно, чтобы преобразовать его в csr_matrix, из-за дальнейших вычислений, таких как:

matrix = foo(...) 
result = matrix.T.dot(x) 

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

В принципе у меня есть следующие требования:

  • Матрица должна хранить значения с плавающей точкой формы 0. до 1.
  • мне нужно вычислить транспонирование матрицы
  • Мне нужно вычислить Скалярное произведение с вектором x_dimensional
  • размеры матрицы может быть около 1 * 10^9 х 1 * 10^8

Мой набегающего хранение превышает. Я читал несколько сообщений о переполнении стека и остальной части Интернета;) Я нашел PyTables, который на самом деле не сделан для матричных вычислений ... и т. Д. Есть ли лучший способ?

+0

Я думаю, что это может быть скорее вопрос математического/численного анализа :) В моем Num.Anal. Конечно, единственный способ сделать матрицу такого размера - сделать ее тридиагональной. –

+0

Кроме того, я знаю, что вы запрашиваете numpy, но у меня есть немного законченная библиотека для python. [Это на github] (https: // github.com/Twoody/Lin_Alg_py) –

+0

Когда вы задали этот вопрос, оказалось, что вы хотите хранить поплавки, но вы приняли ответ, который предложил ints. Мне просто интересно - чего я здесь пропустил? Благодаря! –

ответ

2

Возможно, вы достигли предела того, что может сделать для вас Python, или вы можете сделать немного больше. Попробуйте установить тип данных np.float32, если вы находитесь на 64-битной машине, эта уменьшенная точность может снизить потребление памяти. np.float16 может помочь вам на память еще больше, но ваши расчеты могут замедлить (я видел примеры, где обработка может занять в 10 раз количество времени):

matrix = dok_matrix((dim_x, dim_y), dtype=np.float32)  

или, возможно, гораздо медленнее, но даже меньше потребление памяти:

matrix = dok_matrix((dim_x, dim_y), dtype=np.float16)  

Другой вариант: купить больше системной памяти.


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

2

В вашем случае я бы рекомендовал использовать тип данных np.int8 (или np.uint8), который требуется только один байт для каждого элемента:

matrix = dok_matrix((dim_x, dim_y), dtype=np.int8) 

Непосредственно построении csr_matrix также позволит вам идти дальше с максимальным размером матрицы :

from scipy.sparse import csr_matrix 

def foo(*args): 
    dim_x = 256*256*1024 
    dim_y = 128*128*512 
    row = [] 
    col = [] 

    for i in range(dim_x): 
     # compute stuff in order to get j 
     row.append(i) 
     col.append(j) 
    data = np.ones_like(row, dtype=np.int8) 

    return csr_matrix((data, (row, col)), shape=(dim_x, dim_y), dtype=np.int8) 
Смежные вопросы