Disons que j'ai

arr = np.arange(6)
arr
array([0, 1, 2, 3, 4, 5])

Et je décide que je veux traiter un tableau "comme un cercle": quand je manque de matériel à la fin, je veux recommencer à l'index 0. Autrement dit, je veux un moyen pratique de sélectionner des éléments x, en commençant à l'index i.

Maintenant, si x == 6, je peux simplement faire

i = 3
np.hstack((arr[i:], arr[:i]))
Out[9]: array([3, 4, 5, 0, 1, 2])

Mais existe-t-il un moyen pratique de le faire généralement, même si x > 6, sans avoir à casser manuellement le tableau et à réfléchir à la logique?

Par exemple:

print(roll_array_arround(arr)[2:17])

Devrait revenir.

array([2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0])
2
FooBar 12 avril 2018 à 11:06

4 réponses

Meilleure réponse

Voir mode = 'wrap' dans ndarray.take:

https://docs.scipy.org/doc/numpy/reference/generated/numpy.take.html

Prendre votre fonction hypothétique:

print(roll_array_arround(arr)[2:17])

S'il est implicite qu'il s'agit d'une véritable tranche du tableau d'origine que vous recherchez, cela ne se produira pas; un tableau encapsulé ne peut pas être exprimé sous la forme d'une vue étirée de l'original; donc si vous recherchez une fonction qui mappe un ndarray à un ndarray, cela impliquera nécessairement une copie de vos données.

Autrement dit, en termes d'efficacité, vous ne devez pas vous attendre à trouver une solution dont les performances diffèrent considérablement de l'expression ci-dessous.

print(arr.take(np.arange(2,17), mode='wrap'))
2
Eelco Hoogendoorn 12 avril 2018 à 09:32

Une solution que vous pourriez envisager serait probablement:

from itertools import cycle
list_to_rotate = np.array([1,2,3,4,5])
rotatable_list = cycle(list_to_rotate)
1
Kenstars 12 avril 2018 à 08:29

Le fonctionnement du module semble être le meilleur ajustement ici -

def rolling_array(n, x, i):
    # n is rolling period
    # x is length of array
    # i is starting number
    return np.mod(np.arange(i,i+x),n)

Exemples de séries -

In [61]: rolling_array(n=6, x=6, i=3)
Out[61]: array([3, 4, 5, 0, 1, 2])

In [62]: rolling_array(n=6, x=17, i=2)
Out[62]: array([2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0])
2
Divakar 12 avril 2018 à 08:22

Vous devez roll votre tableau.

>>> x = np.arange(10)
>>> np.roll(x, 2)
array([8, 9, 0, 1, 2, 3, 4, 5, 6, 7])

Voir la documentation numpy pour plus de détails.

-1
Anand Chitipothu 12 avril 2018 à 08:11