2017-04-15 1 views
0

J'essaie de comparer des valeurs dans un tableau np, de les ajouter séquentiellement et de créer un vecteur contenant les plus petites valeurs du tableau np (le vecteur doit avoir la longueur N * 2 - 1, si les dimensions de la matrice sont NxN). J'ai joint une image pour mieux illustrer le problème. Fondamentalement, je veux commencer à la position [0,0] et ensuite comparer séquentiellement les valeurs dans [0,1] et [1,0], etc. Quand un nan est comparé à un nombre, il sélectionne automatiquement le nombre. Pour la comparaison de deux nombres, c'est-à-dire les valeurs dans [0,2] et [1,1], il convient de sélectionner la plus petite.Comparaison judicieuse des éléments dans le même tableau np Python

5x5nparray

La raison pour laquelle la matrice est une matrice triangulaire supérieure avec des valeurs nan affiché à la place des 0, est que la matrice est symétrique et je pensais que ce serait faire le calcul du vecteur avec les valeurs plus petites il est plus facile . Ci-dessous, est un code que j'ai écrit, dans une tentative de résoudre le problème. Je me rends compte que les index i et j se déplacent incorrectement à travers la matrice, cependant, je suis totalement perdu sur la façon de le faire correctement.

NOTE: Je n'ai pas inclus le code qui génère la matrice, simplement parce qu'il fait partie d'un script plus grand et que je voulais éviter toute confusion. J'ai noté dim = 5 pour la matrice (mat) de taille 5x5 dans cet exemple. De plus, ce n'est qu'un exemple où les valeurs minimales sont [mat [0,0], mat [0,1], mat [1,1], mat [1,2] ...].

x=[] 
dim = 5 
for i in range(dim-1): 
    for j in range(dim-1): 

    if mat[i,j+1] > mat[i+1,j]: 
     x.append(mat[i+1,j]) 

    elif mat[i,j+1] < mat[i+1,j]: 
     x.append(mat[i,j+1]) 

    elif m.isnan(mat[i,j+1]): 
     x.append(mat[i+1,j]) 

    elif m.isnan(mat[i+1,j]): 
     x.append(mat[i,j+1]) 

J'apprécierais toute aide/conseils avec ceci.

EDIT:

Merci pour tous vos commentaires. Je pense que j'ai compris comment le faire. Je pense qu'il y a probablement une façon plus pythonique de le faire, cependant, je n'ai pas les compétences pour le moment. Le coup de code devrait être capable de traverser une matrice triangulaire supérieure en choisissant les plus petites valeurs et en les ajoutant à un vecteur. Dans le cas de cet exemple, je veux dire vecteur = [2,8, 4,7, 7,6, 5,5, 5,3, 0,18, -3,9, -11,1, -20,1].

import numpy as np 


dim = 5 
mat = np.array([[2.802, 4.713, 9.581, 15.339, 22.273], 
    [np.nan, 7.647, 5.559, 7.317, 10.250], 
    [np.nan, np.nan, 5.383, 0.184, -0.882], 
    [np.nan, np.nan, np.nan, -3.992, -11.124], 
    [np.nan, np.nan, np.nan, np.nan, -20.192]]) 
mat_to_vect = np.reshape(mat, (dim**2)) 
min_vect = [mat_to_vect[0]] 

i = 1 
j = dim 

while i and j < dim**2-1: 

    if mat_to_vect[i] > mat_to_vect[j]: 
     min_vect.append(mat_to_vect[j]) 
     j += dim 
     i += dim 

    elif mat_to_vect[i] < mat_to_vect[j]: 
     min_vect.append(mat_to_vect[i]) 
     j += 1 
     i += 1 

    elif m.isnan(mat_to_vect[i]): 
     min_vect.append(mat_to_vect[j]) 
     j += dim 
     i += dim 

    elif m.isnan(mat_to_vect[j]): 
     min_vect.append(mat_to_vect[i]) 
     j += 1 
     i += 1 

min_vect.append(mat_to_vect[dim**2-1]) 
+0

Est-ce que vous essayez de faire, ajoutez le plus petit nombre de chaque colonne à une _vector_? Pourriez-vous expliquer à quoi correspondent les «plus petites valeurs»? – nikjohn

+0

Désolé, je n'étais pas clair. Si je commence à mat [0,0] alors je voudrais comparer les valeurs mat [0,1] et mat [1,0]. Dans ce cas, mat [1,0] = nan, donc mat [0,1] devrait être ajouté à x. L'étape suivante consiste à comparer mat [0,2] et mat [1,1], ici mat [1,1] Jond

+0

Vous devriez considérer l'option d'utiliser une méthode intégrée comme le numpy.matrix.min() voir la documentation de numpy: https://docs.scipy.org/doc/numpy/reference/generated/numpy.matrix.min.html. Une solution similaire, mais peut-être mieux pour votre cas, a été fournie par @NaN. – nikjohn

Répondre

0
import numpy as np 


dim = 5 
mat = np.array([[2.802, 4.713, 9.581, 15.339, 22.273], 
    [np.nan, 7.647, 5.559, 7.317, 10.250], 
    [np.nan, np.nan, 5.383, 0.184, -0.882], 
    [np.nan, np.nan, np.nan, -3.992, -11.124], 
    [np.nan, np.nan, np.nan, np.nan, -20.192]]) 
mat_to_vect = np.reshape(mat, (dim**2)) 
min_vect = [mat_to_vect[0]] 

i = 1 
j = dim 

while i and j < dim**2-1: 

    if mat_to_vect[i] > mat_to_vect[j]: 
     min_vect.append(mat_to_vect[j]) 
     j += dim 
     i += dim 

    elif mat_to_vect[i] < mat_to_vect[j]: 
     min_vect.append(mat_to_vect[i]) 
     j += 1 
     i += 1 

    elif m.isnan(mat_to_vect[i]): 
     min_vect.append(mat_to_vect[j]) 
     j += dim 
     i += dim 

    elif m.isnan(mat_to_vect[j]): 
     min_vect.append(mat_to_vect[i]) 
     j += 1 
     i += 1 

min_vect.append(mat_to_vect[dim**2-1]) 
0

Ceci est trop grand pour un commentaire, mais peut servir à fournir quelques options à votre solution finale.

a = [[2.802, 4.713, 9.581, 15.339, 22.273], 
    [np.nan, 7.647, 5.559, 7.317, 10.250], 
    [np.nan, np.nan, 5.383, 0.184, -0.882], 
    [np.nan, np.nan, np.nan, -3.992, -11.124], 
    [np.nan, np.nan, np.nan, np.nan, -20.192]] 
b = np.nanmin(a, axis=0) 
b 
array([ 2.802, 4.713, 5.383, -3.992, -20.192]) 

Maintenant si -20.192 le résultat souhaité, alors la solution finale est simple. En fait, cette configuration de l'utilisation d'un np.triu avec la partie inférieure définie sur np.nan permet d'utiliser les fonctions nan pour obtenir les minimums. Dans votre cas, obtenez le minimum par colonne, puis enfin par ligne, si -20.192 serait le résultat souhaité. Si ce n'est pas le cas final, les étapes consistant à passer successivement de la cellule (0,0) à travers le réseau doivent être définies plus en détail. En bref, np.nanmin semble être ce que vous cherchez.

ADDENDA Ou vous pouvez le faire de manière séquentielle, que je pense que vos ajouts dans les commentaires font référence à

a 
array([[ 2.802, 4.713, 9.581, 15.339, 22.273], 
     [ nan, 7.647, 5.559, 7.317, 10.25 ], 
     [ nan,  nan, 5.383, 0.184, -0.882], 
     [ nan,  nan,  nan, -3.992, -11.124], 
     [ nan,  nan,  nan,  nan, -20.192]]) 

b = [np.nanmin(a[:i], axis=0) for i in range(1, a.shape[0]+1)] 
b 
[array([ 2.802, 4.713, 9.581, 15.339, 22.273]), 
array([ 2.802, 4.713, 5.559, 7.317, 10.25 ]), 
array([ 2.802, 4.713, 5.383, 0.184, -0.882]), 
array([ 2.802, 4.713, 5.383, -3.992, -11.124]) 
array([ 2.802, 4.713, 5.383, -3.992, -20.192])]] 
+0

Nous vous remercions de votre suggestion. J'ai répondu ci-dessus dans la section des commentaires. – Jond

+0

@Jond L'ajout est-il supérieur à ce que vous recherchez? – NaN

+0

merci pour votre commentaire. Je ne suis pas sûr comment le code ci-dessus obtiendra x = [2.8, 4.7, 7.6, 5.5, 5.3, 0.18, -3.9, -11.1, -20.1]. J'ai édité mon post original, ce qui me donne le résultat souhaité. La boucle while vérifie fondamentalement à chaque point quelles valeurs sont plus petites et ensuite l'ajoute. Si c'est comparer entre un nan et un nombre il choisit le nombre. – Jond