Нарезка ndarrays по границам массива

Вопрос:

учитывая ndarray:

In [2]: a
Out[2]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

Я ищу рутину, дающую мне:

array([7, 8, 9, 0, 1])

Ex.: Начиная с индекса 8, пересекая границу массива и заканчивая индексом 2 (включительно). Если я использую нарезку, я (конечно) получаю:

In [3]: a[-3:2]
Out[3]: array([], dtype=int64)

Возможный ответ:

Это использовать функцию крена.

In [5]: np.roll(a,3)[:5]
Out[5]: array([7, 8, 9, 0, 1])

Что я ищу:

Что мне не нравится в этом, так это то, что это не так просто, как нарезка. Поэтому я ищу что-то вроде:

In [6]: a.xxx[-3:2]

Синтаксис, подобный этому, существует, например, в pandas.DataFrame.iloc. Заранее большое спасибо!

Примечание: iloc, не делает то, что я хочу. Я просто сослался на синтаксис (который мне нравится). Спасибо за комментарий, cᴏʟᴅsᴘᴇᴇᴅ

3 ответа

Решение

использовать np.arange()

Через 3 года после того, как я задал этот квест, это просто пришло мне в голову ...

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

В python/numpy нет механизма нарезки, который автоматически оборачивает списки / массивы (как круглые контейнеры), как вы, похоже, ищете, так что на самом деле единственный способ сделать это - использовать функции. Что вы делаете с roll это красиво и компактно, даже если это не так идиоматично, как вам нравится. Ниже я обрисовал пару (немного больше) идиоматических / питонных решений, которые делают то же самое.

Опция 1
np.take на основании комментария hpaulj:

np.take(a, range(len(a) - 3, len(a) + 2), mode='wrap')
array([7, 8, 9, 0, 1])

Вариант 2
isliceв cycle объект:

from itertools import islice, cycle

list(islice(cycle(a), len(a) - 3, len(a) + 2))
[7, 8, 9, 0, 1] 

Не так красиво, как раствор или прокатка холодных скоростей, но

def over_edge_slicing(arr, start, end):
    return np.append(arr[start:], arr[:end])

a = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
print(over_edge_slicing(a, -3, 2))

был бы другой способ написать это. Однако вы теряете общность (вы не можете использовать это, например, для нарезки из индекса 2-4).

Другие вопросы по тегам