Chcę iteracyjnie budować macierze rzadkie, i zauważył, że istnieją dwa odpowiednie opcje to zgodnie z dokumentacją scipy:Dlaczego lil_matrix i dok_matrix są tak powolne w porównaniu do zwykłego dyktowania dyktowanych?
klasy scipy.sparse.lil_matrix (arg1, kształt = None , dtype = Brak, copy = False) [źródło] Lista rzadka połączona wierszami
Jest to wydajna struktura do budowania rzadkich macierzy przyrostowo.
klasy scipy.sparse.dok_matrix (arg1, kształt = None, dtype = None, kopii = False) [źródło] Słownik kluczy podstawie macierz rzadką.
Jest to wydajna struktura do budowania rzadkich macierzy przyrostowo.
Ale kiedy biegnę odniesienia w stosunku do budowy słownika słownika wartości (które później można łatwo przekształcić do rozrzedzony matrycy), ten ostatni okazuje się około 10-20 razy szybciej niż przy użyciu dowolnego rzadki modele macierzy:
from scipy.sparse import dok_matrix, lil_matrix
from timeit import timeit
from collections import defaultdict
def common_dict(rows, cols):
freqs = defaultdict(lambda: defaultdict(int))
for row, col in zip(rows, cols):
freqs[row][col] += 1
return freqs
def dok(rows, cols):
freqs = dok_matrix((1000,1000))
for row, col in zip(rows, cols):
freqs[row,col] += 1
return freqs
def lil(rows, cols):
freqs = lil_matrix((1000,1000))
for row, col in zip(rows, cols):
freqs[row,col] += 1
return freqs
def benchmark():
cols = range(1000)
rows = range(1000)
res = timeit("common_dict({},{})".format(rows, cols),
"from __main__ import common_dict",
number=100)
print("common_dict: {}".format(res))
res = timeit("dok({},{})".format(rows, cols),
"from __main__ import dok",
number=100)
print("dok: {}".format(res))
res = timeit("lil({},{})".format(rows, cols),
"from __main__ import lil",
number=100)
print("lil: {}".format(res))
Wyniki:
benchmark()
common_dict: 0.11778324202168733
dok: 2.2927695910912007
lil: 1.3541790939634666
Co to jest, że powoduje takie obciążenie dla modeli macierzy, i czy istnieje jakiś sposób, aby ją przyspieszyć? Czy są przypadki użycia, w których albo dok, albo lil wolą nad powszechnym dyktowaniem dyktów?
W moim systemie 'fast_dok' jest około cztery razy wolniejsze niż' common_dict' i osiem razy wolniejsze niż 'tuple_dict', co jest tym, co nazwałem twoim pierwszym przykładem. –
Cont: Nie jestem pewien, dlaczego: może to być spowodowane tym, że tworzysz 'dict' dla każdej pary, a może w czasie pisania' dok_matrix' nie przesłaniało 'get()', a teraz robi? Na szczęście 'update()' nie jest jeszcze przesłonięte, więc pierwsze rozwiązanie działa i jest bardzo szybkie. Jedno zastrzeżenie: wszystkie '0' w' defaultdict' będą również przechowywane przez wynikowy "dok_matrix"; na szczęście można przekonwertować dane na np. 'csr_matrix', a następnie wywołaj' wyelimin_zeros() '. –
Py3.6 ma nowy kod 'dict' (domyślnie uporządkowany itp.), Więc mogą wystąpić zmiany prędkości. – hpaulj