np.linalg.norm не работает для матрицы CSR - PullRequest
0 голосов
/ 01 декабря 2019

У меня есть матрица 220 000 x 34, представленная в виде матрицы Numpy CSR. Когда я пытаюсь взять строковую норму матрицы, я получаю исключение:

>>> np.linalg.norm(csr)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\IBM_ADMIN\AppData\Local\Programs\Python\Python37\lib\site-packa
ges\numpy\linalg\linalg.py", line 2450, in norm
    sqnorm = dot(x, x)
  File "C:\Users\IBM_ADMIN\AppData\Local\Programs\Python\Python37\lib\site-packa
ges\scipy\sparse\base.py", line 480, in __mul__
    raise ValueError('dimension mismatch')
ValueError: dimension mismatch
>>> csr
<3x2 sparse matrix of type '<class 'numpy.int32'>'
        with 6 stored elements in Compressed Sparse Row format>

Существует ли ограничение на использование методов / функций Numpy с матрицами CSR?

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

Ответы [ 2 ]

2 голосов
/ 01 декабря 2019

numpy функции, не работающие на матрицах sparse - это правило, а не исключение.

Вот обходной путь, работающий непосредственно с представлением csr:

from scipy.sparse import random

A = random(1000,500,format="csr")

def sparse_row_norm(A):
    out = np.zeros(A.shape[0])
    # ufunc.reduceat only works properly for strictly increasing points
    # as a workaround we filter out empty rows
    nz, = np.diff(A.indptr).nonzero()
    out[nz] = np.sqrt(np.add.reduceat(np.square(A.data),A.indptr[nz]))
    return out

# compare to brute force (convert to dense array) method
np.allclose(sparse_row_norm(A),np.linalg.norm(A.A,axis=1))
# True

# results are the same but speed is much better
timeit(lambda:sparse_row_norm(A),number=1000)
# 0.04653145093470812
timeit(lambda:np.linalg.norm(A.A,axis=1),number=1000)
# 1.6365239119622856
0 голосов
/ 01 декабря 2019

Вам нужно:

np.linalg.norm(csr.toarray())

Пример:

import numpy as np
from scipy.sparse import csr_matrix
csr = csr_matrix((3, 4), dtype=np.int8).toarray()
np.linalg.norm(csr)
0.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...