2017-10-13 2 views
1

J'ai un tableau numérique et j'ai besoin d'obtenir (sans changer l'original) le même tableau, mais avec le premier élément placé à la fin. Depuis que je l'utilise beaucoup, je suis à la recherche d'un moyen propre d'obtenir cela. Donc, par exemple, si mon tableau original est [1,2,3,4], je voudrais obtenir un tableau [4,1,2,3] sans modifier le tableau original.Obtenir une partie du tableau plus le premier élément en numpy (De manière pythonique)

J'ai trouvé une solution:

x = [1,2,3,4] 
a = np.append(x[1:],x[0])] 

Cependant, je suis à la recherche d'une façon plus pythonique. Fondamentalement, quelque chose comme ceci:

x = [1,2,3,4] 
a = x[(:1,0)] 

Cependant, cela bien sûr ne fonctionne pas. Existe-t-il une meilleure façon de faire ce que je veux que d'utiliser la fonction append()?

Répondre

1

Vous pouvez utiliser np.roll, à partir de la documentation:

éléments du tableau de rouleau le long d'un axe donné.

Les éléments qui roulent au-delà de la dernière position sont réintroduits en premier au .

np.roll([1,2,3,4], 1) 
# array([4, 1, 2, 3]) 

Pour rouleau dans l'autre sens, utilisez un changement négatif:

np.roll([1,2,3,4], -1) 
# array([2, 3, 4, 1]) 
+1

Avec 'np.roll', vous devez vous rappeler quelle direction est positif et ce qui est négatif, cependant. J'aime plus la version 'append', parce que c'est beaucoup plus clair de quelle façon ça roule. – user2357112

2

np.roll est facile à utiliser, mais pas la méthode la plus rapide. C'est un but général, avec de multiples dimensions et décalages.

Son action peut être simplifiée:

def simple_roll(x): 
    res = np.empty_like(x) 
    res[0] = x[-1] 
    res[1:] = x[:-1] 
    return res 

In [90]: np.roll(np.arange(1,5),1) 
Out[90]: array([4, 1, 2, 3]) 
In [91]: simple_roll(np.arange(1,5)) 
Out[91]: array([4, 1, 2, 3]) 

tests de temps:

In [92]: timeit np.roll(np.arange(1001),1) 
36.8 µs ± 1.28 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each) 
In [93]: timeit simple_roll(np.arange(1001)) 
5.54 µs ± 24.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) 

On pourrait aussi utiliser r_ pour construire un tableau d'index pour faire la copie. Mais il est plus lent (en raison de l'indexation avancée par opposition à trancher):

def simple_roll1(x): 
    idx = np.r_[-1,0:x.shape[0]-1] 
    return x[idx] 
In [101]: timeit simple_roll1(np.arange(1001)) 
34.2 µs ± 133 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)