0
votes

Manière rapide de relâcher des éléments de tableau ou de faire des éléments contigus dans Python

J'ai une matrice 3D de taille massive à traiter. Je souhaite relookez des éléments de suivant

import numpy as np
given_array = np.array([1, 1, 1, 3, 3, 5, 5, 5, 8, 8, 8, 8, 8, 23, 23, 23])
required_array = np.array([0, 0, 0, 1, 1,  2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4])


2 commentaires

Ces éléments sont-ils toujours triés?


Non, ils ne sont pas mais donné_array.sort () peut être utilisé. @ Divaker


3 Réponses :


1
votes

Essayez cela et voyez s'il est assez rapide. Utilisez le inverse retourné par numpy.unique avec l'argument retour_inverse = true : xxx


1 commentaires

Pour np.arange (300 * 300 * 300) .reshape (300 300 300) , np.unique prend 1,74 s ± 15,3 ms par boucle (moyenne ± std. Dev. de 7 exécutions, 1 boucle chacune) tandis que Relabel_Euite prend 979 ms ± 9,92 ms par boucle (moyenne ± STD. Dev. de 7 courses, 1 boucle chacune) < / code>. Je traite avec des réseaux 2000 x 2000x 2000 3D. @ Warren weckesser



2
votes

Le moyen le plus rapide devrait être d'écrire une fonction numba spécifique adaptée à ce que vous voulez.

Exemple xxx

sortie Xxx

Cet exemple rend beaucoup d'hypothèses sur l'entrée, c'est-à-dire que la matrice est triée, le premier numéro est positif, il s'agit d'une forme 1D, vous souhaitez écraser le tableau.


3 commentaires

Le code semble fonctionner correctement lorsque le tableau est trié comme vous l'avez mentionné. Pour a = np.random.random_integers (1, 50000, 10000000000) , a.sort () nécessite 7.06 s et après trier Relabel prend uniquement 0,25 s . D'autre part, Relabel_Suite prend 7.5 s . Avez-vous une solution à trier () matrice plus rapide? @ Thane Brooker


@Zak je créerais un tableau de "compteur" 1D avec une longueur correspondant à la taille maximale entière de la matrice d'entrée. Dans votre exemple, ce serait 50000. Ensuite, je voudrais iTERE chaque entier de votre réseau et augmente la cellule du réseau de comptoirs correspondant à l'entier. Donc, si le premier élément de votre tableau était de 25 ans, alors la cellule 25 du compteur augmenterait. Etc. À la fin, je participerais au compteur de compteur et je tiens à la sortie du numéro dans un nouveau tableau. Cela ne nécessiterait qu'une itération de la matrice d'entrée et une itération du compteur.


@Zak j'ai créé ce qui précède dans une nouvelle réponse, permettez-moi de savoir comment les horaires comparent.



2
votes

Si le tableau donné est non traduit, cela sera plus rapide que le trier:

array([0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4])


2 commentaires

Ce code est 5x plus rapide que Relabel_Suite pour np.random.random_integers (1, 50000, 1000000000) . Merci pour ce @thane Brooker, j'accepte cette réponse. Pourquoi ne préférez-vous pas revenir dans la fonction numba? Est-ce que je manque quelque chose? @Thane Brooker


@ZAK La fonction écrase la matrice fournie plutôt que de créer un nouveau tableau. En ne retournant pas de tableau, cela rend ce point évident et il ne peut y avoir de confusion. Si la fonction renvoya un tableau, il serait ambigu de savoir exactement ce qui était renvoyé: - Est-ce que cela renvoie la matrice d'entrée d'origine ou a-t-elle créé un nouveau tableau? Ce n'est donc rien à voir avec Numba, mais il est plutôt plus facile de comprendre que les utilisateurs du code de comprendre ce que le code fait.