2017-02-27 2 views
0

J'ai un très grand numpy.array d'entiers, où chaque entier est compris entre [0, 31].Nombre de fois où l'entier y se produit juste après l'entier x dans un tableau numpy

je voudrais comte, pour chaque paire d'entiers (a, b) dans la gamme [0, 31] (par exemple [0, 1], [7, 9], [18, 0]) la fréquence b se produit juste après a.

Cela me donnerait une matrice de comptes (32, 32).

Je suis à la recherche d'un moyen efficace de le faire avec numpy. Les boucles de python brutes seraient trop lentes.

Répondre

2

est ici une façon ...

Pour rendre l'exemple plus facile à lire, je vais utiliser une valeur maximale de 9 au lieu de 31:

In [178]: maxval = 9 

Faire une entrée aléatoire pour l'exemple:

In [179]: np.random.seed(123) 

In [180]: x = np.random.randint(0, maxval+1, size=100) 

Créer le résultat, d'abord tout 0:

In [181]: counts = np.zeros((maxval+1, maxval+1), dtype=int) 

Maintenant, ajoutez 1 à chaque paire de coordonnées, en utilisant numpy.add.at pour faire en sorte que les doublons sont comptés correctement:

In [182]: np.add.at(counts, (x[:-1], x[1:]), 1) 

In [183]: counts 
Out[183]: 
array([[2, 1, 1, 0, 1, 0, 1, 1, 1, 1], 
     [2, 1, 1, 3, 0, 2, 1, 1, 1, 1], 
     [0, 2, 1, 1, 4, 0, 2, 0, 0, 0], 
     [1, 1, 1, 3, 3, 3, 0, 0, 1, 2], 
     [1, 1, 0, 1, 1, 0, 2, 2, 2, 0], 
     [1, 0, 0, 0, 0, 0, 1, 1, 0, 2], 
     [0, 4, 2, 3, 1, 0, 2, 1, 0, 1], 
     [0, 1, 1, 1, 0, 0, 2, 0, 0, 3], 
     [1, 2, 0, 1, 0, 0, 1, 0, 0, 0], 
     [2, 0, 2, 2, 0, 0, 2, 2, 0, 0]]) 

Par exemple, le nombre de fois 6 est suivi par 1 est

In [188]: counts[6, 1] 
Out[188]: 4 

Nous pouvons vérifier qu'avec l'expression suivante:

In [189]: ((x[:-1] == 6) & (x[1:] == 1)).sum() 
Out[189]: 4 
+0

Ceci est une solution très élégante. Bien que j'ai besoin d'étudier comment cette fonction numpy fonctionne réellement pour comprendre ce qui se passe! – valentin

0

Vous pouvez utiliser la routine diff intégrée de numpy avec des tableaux booléens.

import numpy as np  

test_array = np.array([1, 2, 3, 1, 2, 4, 5, 1, 2, 6, 7]) 
a, b = (1, 2) 

sum(np.bitwise_and(test_array[:-1] == a, np.diff(test_array) == b - a)) 
# 3 

Si votre tableau est multidimensionnel, vous devez d'abord aplatir ou faire au code quelques petites modifications ci-dessus.

+0

Merci pour votre réponse :) Même si votre solution est élégante, elle est en fait plus lente qu'une matière brute boucle python. – valentin