2015-02-09 4 views
7

Предположим, у вас есть следующий Numpy массив,Pythonic способ нарезки из часть Numpy массива

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

и вы хотите, чтобы извлечь новый Numpy массив, состоящий из только первые три (3) и последние четыре (4) элементы, т.е.

>>> y = x[something] 
>>> print y 
[0 1 2 7 8 9 10] 

Возможно ли это? Я знаю, что для извлечения первых трех чисел вы просто делаете x[:3] и для извлечения последних четырех вы делаете x[-4:], но есть ли простой способ извлечь все это в простой фрагмент? Я знаю, что это может быть сделано, например, добавление обоих вызовов,

>>> y = numpy.append(x[:3],x[-4:]) 

но мне было интересно, если есть простой маленький трюк, чтобы сделать это в более прямой, вещий образом, без необходимости ссылаться x снова (т.е. я сначала подумал, что может быть x[-4:3] может работать, но я сразу понял, что это не имело смысла).

+0

Вопрос подобен этому, но предлагаемые решения там не будут работать для более новых версий numpy, поэтому, вероятно, это уже не актуально. Все еще может быть интересно: http://stackoverflow.com/questions/13525266/multiple-slice-in-list-indexing-for-numpy-array – Wolph

ответ

2

Я думаю, вы должны использовать index arrays.

indices = list(range(3))+list(range(-4,0)) 
y = x[indices] 

Вы можете, вероятно, падение list слепков (не уверены, потому что питон 3 изменил поведение немного). Или вы можете использовать numpy жанров.

Edit: не знаю, почему downvote, причиной it works:

import numpy 
x = numpy.array([0,1,2,3,4,5,6,7,8,9,10]) 
indices = list(range(3))+list(range(-4,0)) 
y = x[indices] 
print(y) 
+0

Да, на самом деле это то же самое, что пришло мне в голову после просмотра ответа @mgilson (см. Комментарии). Возможно, если вы добавите то, что мы прокомментировали в этом сообщении относительно использования 'list' вокруг' range', я мог бы принять это как лучший ответ :). –

+0

Я печатал свой ответ перед просмотром комментариев, я хотел сделать это с «динамическими» диапазонами и ссылкой на документы. – luk32

4

Простой срез, вероятно, не будет работать. Вы можете использовать расширенную нарезку Numpy в:

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

Обратите внимание, я прошел в списке индексов, которые я хотел взять из исходного массива ...

Откровенно хотя, ваше решение с np.append, вероятно, так же, как хороший ...

+0

Это может показаться тем же, но теперь, когда я вижу ваш пример, я думаю что элегантный способ сделать то же самое может быть: 'something = range (0,3) + range (-4,0,1)'. Таким образом, общий способ разрезания первых элементов 'n' и последних элементов' m' будет следующим: 'something = range (0, n) + range (-m, 0,1)'! –

+2

Будьте осторожны с добавлением 'range' вместе, в Python 3 они являются объектами' range', а не списками, и поэтому вы получите TypeError. – Ffisegydd

+1

Hi @Ffisegydd; спасибо за вход. Это означает, что более независимым способом выполнения этой версии будет 'something = list (range (0, n)) + list (range (-m, 0,1))'? –

1
np.arange(11)[np.r_[0:3,7:11]] 
# array([ 0, 1, 2, 7, 8, 9, 10]) 

np.r_ является функцией, на самом деле индексируемая объект, в numpy/lib/index_tricks. Он принимает несколько фрагментов или индексов и объединяет их в один массив индексирования.

np.r_[0:3,7:11] 
# array([ 0, 1, 2, 7, 8, 9, 10]) 

Или заимствование из luk32 сек ответа отрицательного среза работа:

a[np.r_[:3,-4:0]] 

Альтернативы сплайсинга 2 части, чтобы удалить середину. s_ позволяет использовать нотацию фрагмента внутри функции.

np.delete(np.arange(11),np.s_[3:7]) 
# array([ 0, 1, 2, 7, 8, 9, 10]) 

Посмотрите на код для .lib.index_tricks, delete и insert функций для большего количества идей о том, как построить индексные массивы из нескольких частей.

Иногда булевский индекс удобен. Сделайте все True или False и переверните выбранные элементы.

i = np.ones(a.shape,dtype='bool') 
i[3:7] = False 
a[i] 
Смежные вопросы