Python / Numpy - обернуть ломтик вокруг конца массива - PullRequest
6 голосов
/ 16 апреля 2011

У меня есть два одномерных массива, один из которых имеет интересующие значения (а), а другой - индексы в этом массиве (b).Я знаю, что значения в b всегда увеличиваются, за исключением одной точки (может быть где угодно), где число уменьшается, поскольку оно катится от конца к началу массива a.Метод ниже, кажется, работает, но я просто думаю, что должен существовать более чистый путь.Кто-нибудь может предложить что-то лучше?Спасибо.

Код:

import numpy as np
a = np.arange(12)
b = np.array([5, 9, 2, 4])
#I want to generate these:
#[5,6,7,8,9]
#[9,10,11,0,1,2]
#[2,3,4]
#[4,5]

a = np.roll(a, -b[0], axis=0)
# Subtract off b[0] but ensure that all values are positive
b = (b-b[0]+len(a))%len(a)
for i, ind in enumerate(b):
   if i < len(b)-1:
      print a[b[i]:b[i+1]+1]
   else:
      print np.hstack((a[b[i]:len(a)], a[0]))

Ответы [ 2 ]

3 голосов
/ 16 апреля 2011

Немного короче, но, может быть, я все еще могу сделать лучше ...

import numpy as np

a = np.arange(12)
b = np.array([5, 9, 2, 4])
b = np.append(b, b[0])

for i in range(0, len(b)-1):
    print np.roll(a, len(a)-b[i])[:b[i+1]-b[i]+1]
0 голосов
/ 14 мая 2014

Не уверен, что это поможет, но быстрый способ без использования памяти a будет следующим:

import numpy as np

a = np.arange(12)
b = np.array([5, 9, 2, 4])
b = np.append(b, b[0])

b2 = b.copy()

b2[(np.diff(b)<0).nonzero()[0]+1:] += a.size

print [np.take(a, np.r_[b2[i]:b2[i+1]+1], mode='wrap') for i in range(b.size-1)]

print [np.roll(a, len(a)-b[i])[:b[i+1]-b[i]+1] for i in range(b.size-1)]

%timeit [np.take(a, np.r_[b2[i]:b2[i+1]+1], mode='wrap') for i in range(b.size-1)]
# 10000 loops, best of 3: 28.6 µs per loop

%timeit [np.roll(a, len(a)-b[i])[:b[i+1]-b[i]+1] for i in range(b.size-1)]
# 10000 loops, best of 3: 77.7 µs per loop
...