scipy.sparse.coo_matrix.max
zwraca maksymalną wartość każdego wiersza lub kolumny, z uwzględnieniem osi. Chciałbym poznać nie wartość, ale indeks maksymalnej wartości każdego wiersza lub kolumny. Nie znalazłem jeszcze sposobu, aby zrobić to w skuteczny sposób, więc chętnie przyjmuję jakąkolwiek pomoc.Argmax każdego wiersza lub kolumny w rzadkiej matrycy scipy
Odpowiedz
Od wersji scipy 0.19, zarówno csr_matrix
, jak i csc_matrix
, obsługujących metody argmax()
i argmin()
.
Jeśli A
to scipy.sparse.coo_matrix
, a następnie pojawi się wiersz i kolumnę o maksymalnej wartości w następujący sposób:
I=A.data.argmax()
maxrow = A.row[I]
maxcol=A.col[I]
Aby uzyskać indeks maksymalnej wartości na każdym rzędzie zobaczyć Edycja:
from scipy.sparse import coo_matrix
import numpy as np
row = np.array([0, 3, 1, 0])
col = np.array([0, 2, 3, 2])
data = np.array([-3, 4, 11, -7])
A= coo_matrix((data, (row, col)), shape=(4, 4))
print A.toarray()
nrRows=A.shape[0]
maxrowind=[]
for i in range(nrRows):
r = A.getrow(i)# r is 1xA.shape[1] matrix
maxrowind.append(r.indices[r.data.argmax()] if r.nnz else 0)
print maxrowind
r.nnz
jest hrabia wyraźnie przechowywanych wartości (czyli wartości niezerowe)
Czy to nie wystarczy, aby uzyskać jedną wartość, a nie dla każdego wiersza lub kolumny? –
Tak, masz rację. Zobacz EDYCJĘ! – xecafe
Proponuję studiując kod
moo._min_or_max_axis
gdzie moo
jest coo_matrix
.
mat = mat.tocsc() # for axis=0
mat.sum_duplicates()
major_index, value = mat._minor_reduce(min_or_max)
not_full = np.diff(mat.indptr)[major_index] < N
value[not_full] = min_or_max(value[not_full], 0)
mask = value != 0
major_index = np.compress(mask, major_index)
value = np.compress(mask, value)
return coo_matrix((value, (np.zeros(len(value)), major_index)),
dtype=self.dtype, shape=(1, M))
W zależności od osi woli pracować z csc nad csr. Nie miałem czasu analizować tego, ale przypuszczam, że powinno być możliwe uwzględnienie w obliczeniach wartości argmax
.
Ta sugestia może nie działać. Kluczem jest metoda mat._minor_reduce
, co robi, z pewnym wyrafinowaniem:
ufunc.reduceat(mat.data, mat.indptr[:-1])
To jest stosuje ufunc
do bloków macierzy macierz data
, używając indptr
do definiowania bloków. np.sum
, np.maxiumum
są ufunc
gdzie to działa. Nie znam odpowiednika o nazwie ufunc argmax
.
Ogólnie rzecz biorąc, jeśli chcesz robić rzeczy według "wiersza" dla matrycy csr (lub kolumny csc), musisz albo powtórzyć wiersz, co jest stosunkowo kosztowne, albo użyć tego , aby zrobić to samo nad płaskim wektorem mat.data
.
group argmax/argmin over partitioning indices in numpy próbuje wykonać argmax.reduceat
. Rozwiązanie może być przystosowane do rzadkiej macierzy.
Tak, http://stackoverflow.com/questions/22124332/group-argmax-argmin-over-partitioning-indices-in-numpy jest logicznie równoważny; po prostu zastosuj do "wskaźników" CSR "indeksu". – joeln
W najnowszej wersji pakietu numpy_indexed (Zastrzeżenie: Jestem jego autorem) może rozwiązać ten problem w sposób skuteczny i elegancki sposób:
import numpy_indexed as npi
col, argmax = group_by(coo.col).argmax(coo.data)
row = coo.row[argmax]
Tu grupy przez kol, więc jej na argmax nad kolumnami ; zamiana wiersza i zmiennej col da ci argmax w wierszach.
Rozszerzenie na odpowiedziach z @hpaulj i @joeln i za pomocą kodu z group argmax/argmin over partitioning indices in numpy jak sugeruje, ta funkcja oblicza argmax nad kolumn dla CSR lub argmax nad rzędami dla CSC:
import numpy as np
import scipy.sparse as sp
def csr_csc_argmax(X, axis=None):
is_csr = isinstance(X, sp.csr_matrix)
is_csc = isinstance(X, sp.csc_matrix)
assert(is_csr or is_csc)
assert(not axis or (is_csr and axis==1) or (is_csc and axis==0))
major_size = X.shape[0 if is_csr else 1]
major_lengths = np.diff(X.indptr) # group_lengths
major_not_empty = (major_lengths > 0)
result = -np.ones(shape=(major_size,), dtype=X.indices.dtype)
split_at = X.indptr[:-1][major_not_empty]
maxima = np.zeros((major_size,), dtype=X.dtype)
maxima[major_not_empty] = np.maximum.reduceat(X.data, split_at)
all_argmax = np.flatnonzero(np.repeat(maxima, major_lengths) == X.data)
result[major_not_empty] = X.indices[all_argmax[np.searchsorted(all_argmax, split_at)]]
return result
Zwraca -1 argmax dowolnych wierszy (CSR) lub kolumn (CSC), które są całkowicie rzadkie (tj. są całkowicie zerowe po X.eliminate_zeros()
).
Możesz spróbować tego: http://stackoverflow.com/a/9337071/1738214 przetwarza każdy wiersz osobno – gcucurull