El método que ya se está utilizando,
A[list1, :][:, list2]
parece ser la forma más rápida para seleccionar los valores deseados de una matriz de repuestos. Vea a continuación un punto de referencia.
Sin embargo, para responder a su pregunta sobre cómo seleccionar los valores de las filas arbitrarias y columnas de A
con un solo índice, que tendría que utilizar los llamados "advanced indexing":
A[np.array(list1)[:,np.newaxis], np.array(list2)]
Con la indexación avanzada Si arr1
y arr2
son NDarrays, el componente de (i,j)
A[arr1, arr2]
es igual
A[arr1[i,j], arr2[i,j]]
Así que usted quiere arr1[i,j]
a ser igual para todos list1[i]
j
, y arr2[i,j]
a ser igual para todos list2[j]
i
.
que se pueden organizar con la ayuda de broadcasting (véase más adelante) mediante el establecimiento de arr1 = np.array(list1)[:,np.newaxis]
, y arr2 = np.array(list2)
.
La forma de arr1
es (len(list1), 1)
mientras que la forma de arr2
es (len(list2),)
que emite a (1, len(list2))
ya que los nuevos ejes se añaden a la izquierda automáticamente cuando sea necesario.
Cada matriz se puede retransmitir a la forma (len(list1),len(list2))
. Esto es exactamente lo que queremos para A[arr1[i,j],arr2[i,j]]
para tener sentido, ya que queremos (i,j)
para ejecutar todos los índices posibles para un conjunto de resultados de la forma (len(list1),len(list2))
.
Este es un caso de microanálisis por una prueba de lo que sugiere que A[list1, :][:, list2]
es la opción más rápida:
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
Esta es la configuración que utilicé para el punto de referencia:
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())
¿Qué enumera1 y lista2 contiene? ¿Qué le da a A [list1: list2]? – Louis
list1 y list 2 son objetos de la lista de Python que contienen enteros, p. Ej. [1,4,6,8] A [list1: list2] está vacío (' \t con 0 elementos almacenados en formato LInked List> –
user972858