unir - tamaño de una matriz en python
Contando elementos distintos de cero dentro de cada fila y dentro de cada columna de una matriz NumPy 2D (4)
Tengo una matriz NumPy
que contiene en su mayoría valores que no son cero, pero ocasionalmente contendrá un valor cero. Necesito poder:
Cuente los valores que no sean cero en cada fila y ponga ese conteo en una variable que pueda usar en las operaciones subsiguientes, tal vez iterando a través de los índices de fila y realizando los cálculos durante el proceso iterativo.
Cuente los valores que no sean cero en cada columna y ponga ese conteo en una variable que pueda usar en las operaciones subsiguientes, tal vez iterando a través de los índices de columna y realizando los cálculos durante el proceso iterativo.
Por ejemplo, una cosa que debo hacer es sumar cada fila y luego dividir cada suma de filas por el número de valores distintos de cero en cada fila, informando un resultado separado para cada índice de fila. Y luego necesito sumar cada columna y luego dividir la suma de la columna por el número de valores que no sean cero en la columna, y también reportar un resultado separado para cada índice de columna. También necesito hacer otras cosas, pero deberían ser fáciles después de descubrir cómo hacer las cosas que estoy enumerando aquí.
El código con el que estoy trabajando está abajo. Puede ver que estoy creando una matriz de ceros y luego la estoy rellenando desde un archivo csv
. Algunas de las filas contendrán valores para todas las columnas, pero otras seguirán teniendo algunos ceros en algunas de las últimas columnas, creando así el problema descrito anteriormente.
Las últimas cinco líneas del código a continuación son de otra publicación en este foro. Estas últimas cinco líneas de código devuelven una lista impresa de índices de fila / columna para los ceros. Sin embargo, no sé cómo usar esa información resultante para crear los conteos de filas no cero y los conteos de columnas no cero descritos anteriormente.
ANOVAInputMatrixValuesArray=zeros([len(TestIDs),9],float)
j=0
for j in range(0,len(TestIDs)):
TestID=str(TestIDs[j])
ReadOrWrite=''Read''
fileName=inputFileName
directory=GetCurrentDirectory(arguments that return correct directory)
inputfile=open(directory,''r'')
reader=csv.reader(inputfile)
m=0
for row in reader:
if m<9:
if row[0]!=''TestID'':
ANOVAInputMatrixValuesArray[(j-1),m]=row[2]
m+=1
inputfile.close()
IndicesOfZeros = indices(ANOVAInputMatrixValuesArray.shape)
locs = IndicesOfZeros[:,ANOVAInputMatrixValuesArray == 0]
pts = hsplit(locs, len(locs[0]))
for pt in pts:
print('', ''.join(str(p[0]) for p in pt))
Puede alguien ayudarme con esto?
(a! = 0) no funciona para matrices dispersas (scipy.sparse.lil_matrix) en mi versión actual de scipy.
Para matrices dispersas hice:
(i,j) = X.nonzero()
column_sums = np.zeros(X.shape[1])
for n in np.asarray(j).ravel():
column_sums[n] += 1.
Me pregunto si hay una forma más elegante.
La forma más rápida es clonar su matriz con valores en lugar de valores reales. Luego simplemente sume por filas o columnas:
X_clone = X.tocsc()
X_clone.data = np.ones( X_clone.data.shape )
NumNonZeroElementsByColumn = X_clone.sum(0)
NumNonZeroElementsByRow = X_clone.sum(1)
Eso funcionó 50 veces más rápido para mí que la solución de Finn Årup Nielsen (1 segundo contra 53)
edición: Tal vez necesite traducir NumNonZeroElementsByColumn en una matriz unidimensional mediante
np.array(NumNonZeroElementsByColumn)[0]
Una forma rápida de contar los elementos distintos de cero por fila en una matriz escasa dispersa m
es:
np.diff(m.tocsr().indptr)
El atributo indptr
de una matriz CSR indica los índices dentro de los datos correspondientes a los límites entre filas. Por lo tanto, calcular la diferencia entre cada entrada proporcionará el número de elementos distintos de cero en cada fila.
Del mismo modo, para el número de elementos distintos de cero en cada columna, utilice:
np.diff(m.tocsc().indptr)
Si los datos ya están en la forma apropiada, se ejecutarán en O ( m.shape[0]
) y O ( m.shape[1]
) respectivamente, en lugar de O ( m.getnnz()
) en las soluciones de Marat y Finn. .
Si necesita los recuentos de nozeros tanto en la fila como en la columna, y, digamos, m
ya es un CSR, puede usar:
row_nonzeros = np.diff(m.indptr)
col_nonzeros = np.bincount(m.indices)
lo que no es asintóticamente más rápido que la primera conversión a CSC (que es O ( m.getnnz()
) ) para obtener col_nonzeros
, pero es más rápido debido a los detalles de la implementación.
import numpy as np
a = np.array([[1, 0, 1],
[2, 3, 4],
[0, 0, 7]])
columns = (a != 0).sum(0)
rows = (a != 0).sum(1)
La variable (a != 0)
es una matriz de la misma forma que la original a
y contiene True
para todos los elementos que no sean cero.
La función .sum(x)
suma los elementos sobre el eje x
. La suma de los elementos True/False
es el número de elementos True
.
Las columns
y rows
variables contienen el número de valores distintos de cero (¡elemento! = 0) en cada columna / fila de su matriz original:
columns = np.array([2, 1, 3])
rows = np.array([2, 3, 1])
EDITAR : El código completo podría verse así (con algunas simplificaciones en su código original):
ANOVAInputMatrixValuesArray = zeros([len(TestIDs), 9], float)
for j, TestID in enumerate(TestIDs):
ReadOrWrite = ''Read''
fileName = inputFileName
directory = GetCurrentDirectory(arguments that return correct directory)
# use directory or filename to get the CSV file?
with open(directory, ''r'') as csvfile:
ANOVAInputMatrixValuesArray[j,:] = loadtxt(csvfile, comments=''TestId'', delimiter='';'', usecols=(2,))[:9]
nonZeroCols = (ANOVAInputMatrixValuesArray != 0).sum(0)
nonZeroRows = (ANOVAInputMatrixValuesArray != 0).sum(1)
EDIT 2 :
Para obtener el valor medio de todas las columnas / filas, use lo siguiente:
colMean = a.sum(0) / (a != 0).sum(0)
rowMean = a.sum(1) / (a != 0).sum(1)
¿Qué desea hacer si no hay elementos que no sean cero en una columna / fila? Entonces podemos adaptar el código para resolver tal problema.