Il metodo si sta già utilizzando,
A[list1, :][:, list2]
sembra essere il modo più veloce per selezionare i valori desiderati da una matrice di pezzi di ricambio. Vedi sotto per un punto di riferimento.
Tuttavia, per rispondere alla tua domanda su come selezionare i valori da righe arbitrari e colonne di A
con un unico indice, si avrebbe bisogno di utilizzare la cosiddetta "advanced indexing":
A[np.array(list1)[:,np.newaxis], np.array(list2)]
Con l'indicizzazione avanzata , se arr1
e arr2
sono NDarrays, la componente (i,j)
di A[arr1, arr2]
uguale
A[arr1[i,j], arr2[i,j]]
Così si vorrebbe arr1[i,j]
eguagliare list1[i]
per tutti j
, e arr2[i,j]
di eguagliare list2[j]
per tutti i
.
che può essere organizzato con l'aiuto di broadcasting (vedi sotto) modificando arr1 = np.array(list1)[:,np.newaxis]
e arr2 = np.array(list2)
.
La forma arr1
è (len(list1), 1)
mentre la forma di arr2
è (len(list2),)
che trasmette a (1, len(list2))
poiché nuovi assi vengono aggiunti automaticamente la partita quando necessario.
Ogni array può essere ulteriormente trasmesso per modellare (len(list1),len(list2))
. Questo è esattamente ciò che vogliamo per A[arr1[i,j],arr2[i,j]]
per avere senso, poiché vogliamo che (i,j)
esegua tutti gli indici possibili per un array di risultati di forma (len(list1),len(list2))
.
Ecco un caso microbenchmark per una prova che suggerisce che A[list1, :][:, list2]
è l'opzione più veloce:
In [32]: %timeit orig(A, list1, list2)
10 loops, best of 3: 110 ms per loop
In [34]: %timeit using_listener(A, list1, list2)
1 loop, best of 3: 1.29 s per loop
In [33]: %timeit using_advanced_indexing(A, list1, list2)
1 loop, best of 3: 1.8 s per loop
Qui è la configurazione che ho usato per il benchmark:
import numpy as np
import scipy.sparse as sparse
import random
random.seed(1)
def setup(N):
A = sparse.rand(N, N, .1, format='lil')
list1 = np.random.choice(N, size=N//10, replace=False).tolist()
list2 = np.random.choice(N, size=N//20, replace=False).tolist()
return A, list1, list2
def orig(A, list1, list2):
return A[list1, :][:, list2]
def using_advanced_indexing(A, list1, list2):
B = A.tocsc() # or `.tocsr()`
B = B[np.array(list1)[:, np.newaxis], np.array(list2)]
return B
def using_listener(A, list1, list2):
"""https://stackoverflow.com/a/26592783/190597 (listener)"""
B = A.tocsr()[list1, :].tocsc()[:, list2]
return B
N = 10000
A, list1, list2 = setup(N)
B = orig(A, list1, list2)
C = using_advanced_indexing(A, list1, list2)
D = using_listener(A, list1, list2)
assert np.allclose(B.toarray(), C.toarray())
assert np.allclose(B.toarray(), D.toarray())
cosa elenca list1 e list2? Cosa dà A [list1: list2] ?? – Louis
lista1 e lista 2 sono oggetti lista python contenenti numeri interi ad es. [1,4,6,8] Un [elenco1: elenco2] è vuoto (<1x3 matrice sparsa di tipo '' \t con 0 elementi memorizzati nel formato Elenco con segno intermedio> –
user972858