2017-10-12 2 views
3

Comment ne pas utiliser FancyIndexing de numpy pour créer, je voudrais les meilleures performances:Comment créer une matrice Numpy utilisant FancyIndexing

array([[ 1, 2, 3, 4, 16, 31], 
     [ 2, 3, 4, 5, 17, 32], 
     [ 3, 4, 5, 6, 18, 33], 
     [ 4, 5, 6, 7, 19, 34], 
     [ 5, 6, 7, 8, 20, 35], 
     [ 6, 7, 8, 9, 21, 36], 
     [ 7, 8, 9, 10, 22, 37], 
     [ 8, 9, 10, 11, 23, 38], 
     [ 9, 10, 11, 12, 24, 39], 
     [10, 11, 12, 13, 25, 40]] 

A partir de ceci:

a = np.arange(0,10) 
    aa = np.arange(0,50) 
    y = 1 
    AA = [(aa[np.array([x+y, 1+x+y, 2+x+y, 3+x+y, 15+x+y, 30+x+y])]) for x, i in enumerate(a)] 

Je reçois cela,

[array([ 2, 3, 4, 5, 17, 32]), 
array([ 3, 4, 5, 6, 18, 33]), 
array([ 4, 5, 6, 7, 19, 34]), 
array([ 5, 6, 7, 8, 20, 35]), 
array([ 6, 7, 8, 9, 21, 36]), 
array([ 7, 8, 9, 10, 22, 37]), 
array([ 8, 9, 10, 11, 23, 38]), 
array([ 9, 10, 11, 12, 24, 39]), 
array([10, 11, 12, 13, 25, 40]), 
array([11, 12, 13, 14, 26, 41])] 
+3

Utiliser 'broadcasting':' np.array ([1, 2, 3, 4, 16, 31]) + np.arange (10) [:, Aucun] '. – Divakar

+0

J'ai besoin de y, une variable - c'est un exemple de jouet .. Je suis en train de trancher 'aa', dans le monde réel. – Merlin

Répondre

3

En utilisant des variables données a, aa et y, voici un à l'aide broadcasting pour l'ajout extérieur -

offset = np.array([0,1,2,3,15,30]) 
out = aa[a[:,None] + offset + y] 

En utilisant add-ufunc's explicit outer method -

out = aa[np.add.outer(a , offset + y)] 

Hors limites cas

Pour en dehors des limites cas (aa étant plus petite que nécessaire), nous pouvons zéros pad avec aa puis les indexer -

offset = np.array([0,1,2,3,15,30]) 
idx = np.add.outer(a , offset + y) 
aa_p = np.pad(aa,(0,idx.max()-len(a)+1), 'constant') 
out = aa_p[idx] 

Ou initialiser tableau de sortie, puis créer un masque de lieux valides pour l'attribution -

offset = np.array([0,1,2,3,15,30]) 
idx = np.add.outer(a , offset + y) 
mask = idx < len(aa) 
out = np.zeros(idx.shape, dtype=aa.dtype) 
out[mask] = aa[idx[mask]] 

entrée d'échantillon, la production -

In [234]: a = np.arange(0,10) 
    ...: aa = np.arange(4,42) 
    ...: y = 6 
    ...: 

In [235]: out 
Out[235]: 
array([[10, 11, 12, 13, 25, 40], 
     [11, 12, 13, 14, 26, 41], 
     [12, 13, 14, 15, 27, 0], 
     [13, 14, 15, 16, 28, 0], 
     [14, 15, 16, 17, 29, 0], 
     [15, 16, 17, 18, 30, 0], 
     [16, 17, 18, 19, 31, 0], 
     [17, 18, 19, 20, 32, 0], 
     [18, 19, 20, 21, 33, 0], 
     [19, 20, 21, 22, 34, 0]]) 
+0

Dois-je remplir le 'aa'? Si le dernier élément de décalage est supérieur à la longueur de 'aa', cela ferait-il exploser - ou envelopper? – Merlin

+0

@Merlin Consultez les modifications. – Divakar

1

Nous pouvons faire ici l'utilisation de la radiodiffusion:

>>> np.arange(0,10).reshape(-1,1) + np.array([*range(1,5),16,31]) 
array([[ 1, 2, 3, 4, 16, 31], 
     [ 2, 3, 4, 5, 17, 32], 
     [ 3, 4, 5, 6, 18, 33], 
     [ 4, 5, 6, 7, 19, 34], 
     [ 5, 6, 7, 8, 20, 35], 
     [ 6, 7, 8, 9, 21, 36], 
     [ 7, 8, 9, 10, 22, 37], 
     [ 8, 9, 10, 11, 23, 38], 
     [ 9, 10, 11, 12, 24, 39], 
     [10, 11, 12, 13, 25, 40]]) 

Ici, nous créons un 10 × une matrice qui varie de 0 à (exclu) 10 et on crée une matrice 1 × 6 avec des données [1,2,3,4,16,31].

Si vous voulez y être le « décalage », vous pouvez l'écrire comme:

>>> y = 1 
>>> np.arange(y,y+10).reshape(-1,1) + np.array([*range(0,4),15,30]) 
array([[ 1, 2, 3, 4, 16, 31], 
     [ 2, 3, 4, 5, 17, 32], 
     [ 3, 4, 5, 6, 18, 33], 
     [ 4, 5, 6, 7, 19, 34], 
     [ 5, 6, 7, 8, 20, 35], 
     [ 6, 7, 8, 9, 21, 36], 
     [ 7, 8, 9, 10, 22, 37], 
     [ 8, 9, 10, 11, 23, 38], 
     [ 9, 10, 11, 12, 24, 39], 
     [10, 11, 12, 13, 25, 40]])