2015-11-05 4 views
3

У меня индексы позиций ненулевых элементов в разреженной матрице в Python в видеДоступ к ненулевым элементам в конкретной строке матрицы в Python

(array([0, 1, 2], dtype=int32), array([2, 0, 0], dtype=int32), array([2, 1, 3])) 

или в матричной форме

[[0 2] 
[1 0] 
[2 0]] 

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

for r in range(rows): 
    A[r,:] = np.dot(B[r,:],C.T) 

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

Часть я не могу получить мою голову вокруг из-за тот факт, что может быть различное количество записей для каждой строки/столбца.

+1

Каким образом использование только ненулевых элементов изменяет окончательный ответ? – hpaulj

+0

Вы установили теги 'scipy' и' редкие матрицы'. Означает ли это, что вы собираетесь использовать матрицы 'scipy.sparse'? Они могут выполнять умножение матрицы (в скомпилированном коде). – hpaulj

+0

проблема состоит в том, что матрица B является редкой и огромной, а затем A и C будут большими, и поэтому для эффективности я хочу только завершить умножение ненулевыми элементами. Есть гораздо больше нулевых элементов, чем ненулевых. Я думаю, что решение, вероятно, связано с scipy.sparse, но я не уверен, и я открыт для идей! –

ответ

1

я узнал, что вы можете использовать булевы индексы массива в Python, так что следующий делает то, что я хотел достичь:

for r in range(rows): 
    A[r,B[r,:]!=0] = np.dot(B[r , B[r,:]!=0], C[: , B[r,:]!=0].T) 

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

1

Я немного озадачен тем, что представляет собой первый кортеж. Являются ли это индексами и значениями разреженного массива? например

In [4]: arrays=(np.array([0, 1, 2], dtype=int), np.array([2, 0, 0], dtype=int), np.array([2, 1, 3], dtype=float)) 
... 
In [6]: from scipy import sparse 
In [7]: M=sparse.csr_matrix((arrays[2],(arrays[0],arrays[1]))) 
In [8]: M 
Out[8]: 
<3x3 sparse matrix of type '<class 'numpy.float64'>' 
    with 3 stored elements in Compressed Sparse Row format> 
In [9]: M.A 
Out[9]: 
array([[ 0., 0., 2.], 
     [ 1., 0., 0.], 
     [ 3., 0., 0.]]) 

In [10]: print(M) 
    (0, 2) 2.0 
    (1, 0) 1.0 
    (2, 0) 3.0 

Умножение матриц определяется для такого массива:

In [12]: M*M.T 
Out[12]: 
<3x3 sparse matrix of type '<class 'numpy.float64'>' 
    with 5 stored elements in Compressed Sparse Row format> 
In [13]: (M*M.T).A 
Out[13]: 
array([[ 4., 0., 0.], 
     [ 0., 1., 3.], 
     [ 0., 3., 9.]]) 
In [14]: M.A.dot(M.A.T) # dense equivalent 
Out[14]: 
array([[ 4., 0., 0.], 
     [ 0., 1., 3.], 
     [ 0., 3., 9.]]) 

Я мог бы реализовать построчно умножения этого массива:

In [21]: A=M.A  # dense array 
In [22]: for r in range(3): 
    print(np.dot(A[r,:],A[r,:])) 
4.0 
1.0 
9.0 
# actually this is just the diagonal 

In [23]: for r in range(3): # or with the nonzero elements 
    I=np.nonzero(A[r,:]) 
    dot = np.dot(A[r,I[0]],A[r,I[0]]) 
    print(dot) 
4.0 
1.0 
9.0 

за то, что он стоит, nonzero возвращает массив, который я скопировал с вашего поста в начале:

In [24]: np.nonzero(A) 
Out[24]: (array([0, 1, 2], dtype=int32), array([2, 0, 0], dtype=int32)) 
In [25]: A[np.nonzero(A)] 
Out[25]: array([ 2., 1., 3.]) 

Редкая матрица также имеет nonzero метод:

In [26]: M.nonzero() 
Out[26]: (array([0, 1, 2], dtype=int32), array([2, 0, 0], dtype=int32)) 

Я чувствую, как я барахтался вокруг, пытаясь понять смысл вопроса и на примере.

Смежные вопросы