Compter les éléments non-zéros dans chaque rangée et dans chaque colonne d'un tableau 2d NumPy
j'ai un NumPy
matrice qui contient principalement des valeurs non-nulles, mais parfois contient une valeur zéro. J'ai besoin d'être en mesure de:
compter les valeurs non nulles dans chaque rangée et mettre ce nombre dans une variable que je peux utiliser dans des opérations ultérieures, peut-être en itérant par des indices de rangée et en effectuant les calculs pendant le processus itératif.
compter les valeurs non nulles dans chaque colonne et mettre ce nombre dans une variable que je peux utiliser dans des opérations ultérieures, peut-être en itérant par des indices de colonne et en effectuant les calculs pendant le processus itératif.
par exemple, une chose que je dois faire est de faire la somme de chaque ligne et puis diviser chaque somme de ligne par le nombre de valeurs non-zéro dans chaque ligne, en déclarant un résultat séparé pour chaque indice de ligne. Et puis je dois faire la somme de chaque colonne et puis diviser la somme de la colonne par le nombre de valeurs non-zéro dans la colonne, déclarant également un séparé résultat pour chaque index de colonne. J'ai besoin de faire d'autres choses aussi, mais il devrait être facile après j'ai trouver comment faire les choses que je suis d'inscription ici.
le code avec lequel je travaille est ci-dessous. Vous pouvez voir que je crée un tableau de zéros et puis le peupler à partir d'un csv
fichier. Certains de ses lignes contiennent des valeurs pour toutes les colonnes, mais d'autres lignes encore quelques zéros en restant dans l'une des dernières colonnes, créant ainsi le problème décrit surtout.
Les cinq dernières lignes du code ci-dessous sont d'une autre publication sur ce forum. Ces cinq dernières lignes de code renvoient une liste imprimée d'indices ligne/colonne pour les zéros. Cependant, je ne sais pas comment utiliser cette information résultante pour créer les nombres de lignes non-zéro et les nombres de colonnes non-zéro décrits ci-dessus.
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))
quelqu'un Peut-il m'aider?
4 réponses
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)
est un tableau de la même forme que l'original a
et il contient True
pour tous les éléments non-zéros.
.sum(x)
la fonction additionne les éléments sur l'axe x
. Somme de True/False
éléments est le nombre de True
éléments.
les variables columns
et rows
contient le nombre non-nul (élément != 0) valeurs dans chaque colonne / ligne de votre tableau original:
columns = np.array([2, 1, 3])
rows = np.array([2, 3, 1])
EDIT: L'ensemble du code pourrait ressembler à ceci (avec quelques simplifications dans le code):
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:
Pour obtenir la valeur moyenne de toutes les colonnes/lignes, utilisez la commande suivante:
colMean = a.sum(0) / (a != 0).sum(0)
rowMean = a.sum(1) / (a != 0).sum(1)
Que voulez-vous faire si il n'y a pas non nulle éléments dans une colonne/ligne? Ensuite, nous pouvons adapter le code pour résoudre un tel problème.
un moyen rapide de compter les éléments non nuls par ligne dans une matrice scipy clairsemée m
est:
np.diff(m.tocsr().indptr)
indptr
attribut D'une matrice CSR indique les indices à l'intérieur des données correspondant aux limites entre les lignes. Ainsi, le calcul de la différence entre chaque entrée fournira le nombre d'éléments non-zéro dans chaque rangée.
de Même, pour le nombre d'éléments non nuls dans chaque colonne, utilisez:
np.diff(m.tocsc().indptr)
Si les données sont déjà dans le formulaire approprié, ces O (m.shape[0]
) et O (m.shape[1]
) respectivement, plutôt que O (m.getnnz()
) dans les solutions de Marat et Finn.
si vous avez besoin à la fois de la ligne et de la colonne nozero compte, et, disons,m
est déjà un RSE, vous pouvez utiliser:
row_nonzeros = np.diff(m.indptr)
col_nonzeros = np.bincount(m.indices)
qui n'est pas asymptotiquement plus rapide que la première conversion en CSC (qui est O (m.getnnz()
)) pour obtenir col_nonzeros
, mais est plus rapide en raison de la mise en œuvre détail.
Le plus rapide est de cloner votre matrice, à la place de vraies valeurs. Alors résumez par lignes ou colonnes:
X_clone = X.tocsc()
X_clone.data = np.ones( X_clone.data.shape )
NumNonZeroElementsByColumn = X_clone.sum(0)
NumNonZeroElementsByRow = X_clone.sum(1)
modifier: Peut-être aurez-vous besoin de traduire NumNonZeroElementsByColumn en 1-dimensional array par
np.array(NumNonZeroElementsByColumn)[0]
(a != 0) ne fonctionne pas pour les matrices éparses (scipy.clairsemé.lil_matrix) dans ma version actuelle de scipy.
Pour les matrices creuses j'ai fait:
(i,j) = X.nonzero()
column_sums = np.zeros(X.shape[1])
for n in np.asarray(j).ravel():
column_sums[n] += 1.
je me demande s'il y a une façon plus élégante.