2
votes

Comment ajouter les indices (x, y) des éléments du tableau (u, v) pour obtenir un tableau d'éléments (x, y, u, v)?

J'ai écrit une fonction qui ajoute les indices de chaque élément du tableau aux éléments.

Exemples:

Le premier élément est [10,11], l'index est [0,0] - > Devient [0,0,10,11]

Le deuxième élément est [12,13], l'indice est [1,0] -> Devient [1,0,12,13]

Comment puis-je optimiser cette fonction? Existe-t-il un moyen plus simple de l'écrire? Toutes les améliorations / recommandations seront appréciées!

Mon projet: J'utilise le flux optique pour obtenir un tableau de magnitudes (u, v), qui représentent les composantes du vecteur de flux optique de chaque pixel. Je voudrais ajouter la position (x, y) des pixels au tableau afin d'obtenir un tableau de (x, y, u, v). Remarque: la position (x, y) est la même que la valeur d'index, ce qui facilite les choses.

Voici mon code:

Input array: 

[[[10 11]
  [12 13]
  [14 15]]

 [[16 17]
  [18 19]
  [20 21]]]



Output array: 

[[[ 0.  0. 10. 11.]
  [ 1.  0. 12. 13.]
  [ 2.  0. 14. 15.]]

 [[ 0.  1. 16. 17.]
  [ 1.  1. 18. 19.]
  [ 2.  1. 20. 21.]]]

def vec_4D (mag_2D):
    vec_4D = np.zeros((mag_2D.shape[0],mag_2D.shape[1],4))
    x = 0
    y = 0
    for row in vec_4D:
        for col in row:
            col[0] = x
            col[1] = y
            col[2] = mag_2D[y][x][0]
            col[3] = mag_2D[y][x][1]
            x += 1
        x=0
        y+=1
    return(vec_4D)

mag_2D = np.array([[[10,11], [12,13], [14,15]], [[16,17], [18,19], [20,21]]])
print(vec_4D(mag_2D))


0 commentaires

3 Réponses :


4
votes

Voici l'inévitable doublure.

>>> np.moveaxis(np.indices(mag_2D.shape[:-1]), 0, -1)[..., ::-1]
array([[[0, 0],
        [1, 0],
        [2, 0]],

       [[0, 1],
        [1, 1],
        [2, 1]]])

Le moyen le plus simple de comprendre cela est de le décomposer:

np.indices crée des indices à partir de la forme

>>> np.moveaxis(np.indices(mag_2D.shape[:-1]), 0, -1)
array([[[0, 0],
        [0, 1],
        [0, 2]],

       [[1, 0],
        [1, 1],
        [1, 2]]])

Ceux-ci sont cependant séparés pour chaque dimension. Pour obtenir les coordonnées "tuples", nous devons déplacer l'axe principal vers la fin:

>>> np.indices(mag_2D.shape[:-1])
array([[[0, 0, 0],
        [1, 1, 1]],

       [[0, 1, 2],
        [0, 1, 2]]])

Ceci est y, x , OP veut x , y

>>> np.concatenate([np.moveaxis(np.indices(mag_2D.shape[:-1]), 0, -1)[..., ::-1], mag_2D], -1)
array([[[ 0,  0, 10, 11],
        [ 1,  0, 12, 13],
        [ 2,  0, 14, 15]],

       [[ 0,  1, 16, 17],
        [ 1,  1, 18, 19],
        [ 2,  1, 20, 21]]])


4 commentaires

Sans explication, cette réponse, même si elle fonctionne dans ce cas, n'a aucune possibilité d'application à d'autres problèmes. Les doublures sont à la mode mais sans explication perdent leur valeur. Peut-être pouvez-vous ajouter quelques mots à votre réponse


@Bazingaa Avez-vous réellement regardé celui-ci? Je dirais que c'est assez explicite, presque comme l'engish ordinaire: "Concaténer les indices pour mag_2D (avec leur axe principal déplacé vers la fin) avec mag_2D lui-même".


..., ne me ressemble pas à un anglais simple et je pense que même les nouveaux venus. Bien sûr, vous êtes au niveau d'anglais C2, donc pour vous, cela semble évident;)


@Bazingaa D'accord, d'accord. J'ai ajouté quelques lignes d'explication.



1
votes

Une version simplifiée de votre approche complémentaire

In [660]: res[:,:,0] = np.arange(arr.shape[1])                                  
In [661]: res[:,:,1] = np.arange(arr.shape[0])[:,None]     # size 2 column                      
In [662]: res                                                                   
Out[662]: 
array([[[ 0,  0, 10, 11],
        [ 1,  0, 12, 13],
        [ 2,  0, 14, 15]],

       [[ 0,  1, 16, 17],
        [ 1,  1, 18, 19],
        [ 2,  1, 20, 21]]])

L'étape suivante a nécessité quelques essais et erreurs. Nous remplissons les index avec la diffusion. Nous avons besoin de tableaux capables de diffuser vers (2,3), les 2 premières dimensions de res .

In [650]: arr = np.arange(10,22).reshape(2,3,2)  
In [658]: res = np.zeros((arr.shape[0],arr.shape[1],4),arr.dtype)               
In [659]: res[:,:,2:] = arr    


0 commentaires

1
votes

Voici un "multi-liner", utilisant np.indices () , et np.concatenate():

[[[ 0  0 10 11]
  [ 1  0 12 13]
  [ 2  0 14 15]]

 [[ 0  1 16 17]
  [ 1  1 18 19]
  [ 2  1 20 21]]]

Test:

import numpy as np

mag_2D = np.array([[[10,11], [12,13], [14,15]], [[16,17], [18,19], [20,21]]])
y_indices,x_indices = np.indices(mag_2D.shape[0:2])
vec_4D_result = np.concatenate((x_indices[:,:,None], 
                                y_indices[:,:,None], 
                                mag_2D[y_indices,x_indices]), axis = -1)
print (vec_4D_result)

Sortie:

y_indices,x_indices = np.indices(mag_2D.shape[0:2])
vec_4D_result = np.concatenate((x_indices[:,:,None], 
                                y_indices[:,:,None], 
                                mag_2D[y_indices,x_indices]), axis = -1)

p >


1 commentaires

La solution que vous proposez est très claire et a été beaucoup plus facile à appliquer à d'autres problèmes que les autres proposés (même s'ils fonctionnent également très bien!). Je modifierai la réponse acceptée à celle-ci. Merci!