2014-07-09 7 views
6

Próbuję manipulować niektórymi danymi w rzadkiej macierzy. Po utworzeniu jednego, jak mogę dodać/zmienić/zaktualizować wartości w nim? Wydaje się to bardzo proste, ale nie mogę go znaleźć w dokumentacji dla rzadkich klas macierzowych lub w Internecie. Myślę, że brakuje mi czegoś kluczowego.Jak edytować komórki w rzadkiej macierzy za pomocą scipy?

To jest moja nieudana próba uczynienia tego w taki sam sposób jak zwykłą tablicę.

>>> from scipy.sparse import bsr_matrix 
>>> A = bsr_matrix((10,10)) 
>>> A[5][7] = 6 

Traceback (most recent call last): 
    File "<pyshell#11>", line 1, in <module> 
    A[5][7] = 6 
    File "C:\Python27\lib\site-packages\scipy\sparse\bsr.py", line 296, in __getitem__ 
    raise NotImplementedError 
NotImplementedError 

Odpowiedz

1

Dokumentacja dla BSR jest tutaj bsr matrix i CSR jest tutaj csr matrix. Może warto byłoby zrozumieć csr przed przejściem do bsr. Jedyną różnicą jest to, że bsr ma wpisy, które same są macierzami, podczas gdy podstawową jednostką w csr jest skalar.

nie wiem, czy są bardzo proste sposoby, aby manipulować matryce gdy są one tworzone, ale oto kilka przykładów tego, co próbujesz zrobić,

import numpy as np 
from scipy.sparse import bsr_matrix, csr_matrix 

row = np.array([5]) 
col = np.array([7]) 
data = np.array([6]) 
A = csr_matrix((data,(row,col))) 

Jest to prosta składnia w którym wymienione są wszystkie potrzebne dane w macierzy w macierzy w tablicy data, a następnie należy określić, gdzie te dane powinny przejść, używając row i . Zauważ, że spowoduje to, że wymiary matrycy będą wystarczająco duże, aby pomieścić element w największym rzędzie i kolumnie (w tym przypadku macierz 6x8). Możesz zobaczyć macierz w standardowej postaci, używając metody todense().

A.todense() 

Nie można jednak manipulować matrycą w locie za pomocą tego wzoru. Możesz zmodyfikować natywną reprezentację scipy macierzy. Obejmuje to 3 atrybuty, indices, indptr i data. Na początek możemy sprawdzić wartość tych atrybutów dla tablicy, którą już utworzyliśmy.

>>> print A.data 
array([6]) 

>>> print A.indices 
array([7], dtype=int32) 

>>> print A.indptr 
array([0, 0, 0, 0, 0, 0, 1], dtype=int32) 

data to samo było wcześniej, tablica 1-d wartości chcemy w matrycy. Różnica polega na tym, że pozycja tych danych jest teraz określona przez indices i indptr zamiast row i col. indices jest dość prosty. Jest to po prostu lista, w której kolumnie znajduje się każdy wpis danych. Zawsze będzie miał taki sam rozmiar i tablicę data. indptr jest nieco trudniejsze. Pozwala struktura danych, co rząd każdy wpis danych. Aby zacytować docs,

indeksy kolumn dla rzędu i są przechowywane w indices[indptr[i]:indptr[i+1]]

Z tej definicji widzimy, że rozmiar indptr będzie zawsze liczbą rzędów w macierzy + 1. Przyzwyczajenie się do niej zajmuje trochę czasu, ale praca z wartościami dla każdego rzędu da ci pewną intuicję. Zauważ, że wszystkie wpisy są zerowe do ostatniego. Oznacza to, że indeksy kolumn dla wierszy i=0-4 będą przechowywane w indices[0:0], tj. Pustej tablicy. To dlatego, że wszystkie te wiersze są zerami. Wreszcie, w ostatnim rzędzie, i=5 otrzymujemy indices[0:1]=7 który mówi nam wprowadzanie danych (-y) data[0:1] są w wierszu 5 kolumna 7.

Teraz załóżmy, że chcemy dodać wartość 10 w wierszu 2 kolumnie 4.My najpierw umieścić go w atrybucie data,

A.data = np.array([10,6]) 

obok aktualizujemy indices wskazać kolumna 10 będzie,

A.indices = np.array([4,7], dtype=np.int32) 

i wreszcie wskazać, które rząd będzie w modyfikując indptr

Ważne jest, aby typ danych był następujący: indices i indptrnp.int32. Jednym ze sposobów wizualizacji tego, co się dzieje w indptr, jest zmiana liczby podczas przechodzenia z i do i+1 wiersza z danymi. Należy również pamiętać, że tablice takie jak te mogą być wykorzystane do skonstruowania macierzy rzadkich

B = csr_matrix((data,indices,indptr)) 

Byłoby miło, gdyby to było tak proste, jak po prostu indeksowania do tablicy, jak próbował, ale realizacja nie jest tam jeszcze. To powinno wystarczyć, abyś przynajmniej zaczął.

5

Istnieje kilka formatów macierzy rzadkich. Niektóre lepiej nadają się do indeksowania. Jeden, który to zaimplementował to lil_matrix.

Al = A.tolil() 
Al[5,7] = 6 # the normal 2d matrix indexing notation 
print Al 
print Al.A # aka Al.todense() 
A1 = Al.tobsr() # if it must be in bsr format 

Dokumentacja każdego formatu sugeruje, w czym jest dobra, a gdzie jest zła. Ale nie ma uporządkowanej listy, które mają określone operacje.

Advantages of the LIL format 
    supports flexible slicing 
    changes to the matrix sparsity structure are efficient 
    ... 
Intended Usage 
    LIL is a convenient format for constructing sparse matrices 
    ... 

dok_matrix wykonuje również indeksowanie.

Podstawowa struktura danych dla coo_matrix jest łatwa do zrozumienia. Jest to w zasadzie parametry dla definicji coo_matrix((data, (i, j)), [shape=(M, N)]). Aby utworzyć taką samą matrycę można użyć:

sparse.coo_matrix(([6],([5],[7])), shape=(10,10)) 

Jeśli masz więcej zadań, budować większe data, i, j list (albo 1d tablice), a po zakończeniu skonstruować macierz rzadką.