Supongamos que tengo una matriz NxN M (lil_matrix o csr_matrix) de scipy.sparse, y quiero hacer que (N + 1) xN donde M_modified [i, j] = M [i, j] para 0 < = i < N (y todos j) y M [N, j] = 0 para todos j. Básicamente, quiero agregar una fila de ceros a la parte inferior de M y conservar el resto de la matriz. ¿Hay alguna manera de hacer esto sin copiar los datos?expandiendo (agregando una fila o columna) una matriz scipy.sparse
Respuesta
No creo que haya ninguna forma de escapar realmente de la copia. Ambos tipos de matrices dispersas almacenan sus datos como matrices Numpy (en los atributos de datos e índices para csr y en los atributos de datos y filas para lil) internamente y las matrices Numpy no se pueden extender.
actualización con más información:
LIL significa la sigla lista enlazada, pero la implementación actual no está a la altura de su nombre. Las matrices Numpy utilizadas para data
y rows
son ambas de tipo objeto. Cada uno de los objetos en estas matrices son en realidad listas de Python (una lista vacía cuando todos los valores son cero en una fila). Las listas de Python no son listas exactamente vinculadas, pero son bastante cercanas y, francamente, una mejor opción debido a la búsqueda O (1). Personalmente, no veo el punto de usar aquí una matriz de objetos Numpy en lugar de solo una lista de Python. Con bastante facilidad, podría cambiar la implementación de lil actual para usar listas de Python que le permitirían agregar una fila sin copiar toda la matriz.
No estoy seguro si aún está buscando una solución, pero quizás otros pueden consultar hstack
y vstack
- http://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.hstack.html. Creo que podemos definir un csr_matrix para la única fila adicional y luego vstack
con la matriz anterior.
[código fuente para vstack] (https://github.com/scipy/scipy/blob/v0.19.0/scipy/sparse/construct.py#L461-L492) Como esto implica, devuelve una nueva copia de la entrada matrices, por lo tanto, no es lo suficientemente eficiente si queremos expandir una matriz ** en el lugar **. – JenkinsY
Scipy no tiene una forma de hacer esto sin copiar los datos, pero puede hacerlo usted mismo cambiando los atributos que definen la matriz dispersa.
Hay 4 atributos que componen el csr_matrix:
datos: Una matriz que contiene los valores reales en la matriz
índices: Una matriz que contiene el índice de la columna correspondiente a cada valor de datos
indptr: una matriz que especifica el índice antes del primer valor en los datos para cada fila. Si la fila está vacía, el índice es el mismo que la columna anterior.
forma: Una tupla que contiene la forma de la matriz
Si sólo está añadiendo una fila de ceros hasta el fondo todo lo que tiene que hacer es cambiar la forma y indptr para su matriz.
x = np.ones((3,5))
x = csr_matrix(x)
x.toarray()
>> array([[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.]])
# reshape is not implemented for csr_matrix but you can cheat and do it yourself.
x._shape = (4,5)
# Update indptr to let it know we added a row with nothing in it. So just append the last
# value in indptr to the end.
# note that you are still copying the indptr array
x.indptr = np.hstack((x.indptr,x.indptr[-1]))
x.toarray()
array([[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.],
[ 0., 0., 0., 0., 0.]])
Aquí está una función para manejar el caso más general de vstacking de cualquier 2 csr_matrices. Todavía terminas copiando las matrices numpy subyacentes, pero todavía es significativamente más rápido que el método scipy vstack.
def csr_vappend(a,b):
""" Takes in 2 csr_matrices and appends the second one to the bottom of the first one.
Much faster than scipy.sparse.vstack but assumes the type to be csr and overwrites
the first matrix instead of copying it. The data, indices, and indptr still get copied."""
a.data = np.hstack((a.data,b.data))
a.indices = np.hstack((a.indices,b.indices))
a.indptr = np.hstack((a.indptr,(b.indptr + a.nnz)[1:]))
a._shape = (a.shape[0]+b.shape[0],b.shape[1])
return a
Creo que puede salirse con la suya sin devolver 'a', ya que los argumentos de funciones se pasan por referencia,' a' se modifica directamente incluso dentro del alcance de la función. Además, ¿puede haber un análogo csc_happend (a, b)? – richizy
Buena idea, simplemente restablecer la forma. – Jan
- 1. Copie una fila o columna de una matriz e insértela en la siguiente fila/columna
- 2. scipy.sparse: Establecer fila a ceros
- 3. Agregando valores a una matriz usando vectores de índice que incluyen nombres de fila y columna
- 4. agregando una descripción de columna
- 5. Fila eficientemente Estandarizar una matriz
- 6. Determinando el tamaño de byte de una matriz scipy.sparse?
- 7. Seleccionar una columna específica en cada fila de la matriz
- 8. Iteración a través de un vector scipy.sparse (o matriz)
- 9. ¿Cómo se multiplica por elementos una matriz scipy.sparse por una matriz 1d densa emitida?
- 10. Obtenga una columna diferente en cada fila
- 11. agregando una columna en el procedimiento almacenado
- 12. Slickgrid agregar color a una celda/columna o fila
- 13. Suma una fila de una matriz NumPy
- 14. Potencia de elemento de scipy.sparse matriz
- 15. Agregando a una matriz multidimensional en PHP
- 16. jQuery - agregando elementos en una matriz
- 17. ¿Cómo puedo aplicar una función a cada fila/columna de una matriz en MATLAB?
- 18. DataGridViewComboBoxColumn agregando diferentes elementos a cada fila.
- 19. scipy.sparse valor predeterminado
- 20. fila con valor mínimo de una columna
- 21. ¿Cómo obtener una columna de una matriz java 2D?
- 22. Eliminar una columna para una matriz numpy
- 23. ¿Cómo puedo agregar una fila y columna adicionales a una matriz?
- 24. Agregando dinámicamente una fila a las caras de datos dataTable
- 25. Agregando una nueva fila ¿Usando SQL Server Management Studio?
- 26. Cómo subconjuntar la matriz en una columna, mantener el tipo de datos de matriz, mantener los nombres de fila/columna?
- 27. SQL - Insertar múltiples valores de fila en una sola columna
- 28. ¿Hay una manera eficiente de concatenar matrices scipy.sparse?
- 29. ¿Cómo inserto una fila con una columna TimeUUIDType en Cassandra?
- 30. Seleccione una fila con valor distinto de una columna
Si es lo suficientemente crítica para su aplicación, usted podría ser capaz de implementar una nueva clase con la interfaz scipy.sparse que utiliza un tipo de datos más fácilmente extensible bajo el capó. –
Quizás alguien más conocedor de la estructura de datos subyacente pueda responder a esto. Pensé que lil_matrix se implementó con listas vinculadas? – RandomGuy
@scandido, vea si mi última adición responde a su pregunta. –