Numpy индекс срез без потери информации о размерах - PullRequest
77 голосов
/ 24 августа 2010

Я использую numpy и хочу проиндексировать строку, не теряя информацию об измерениях.

import numpy as np
X = np.zeros((100,10))
X.shape        # >> (100, 10)
xslice = X[10,:]
xslice.shape   # >> (10,)  

В этом примере xslice теперь равен 1 измерению, но я хочу, чтобы оно было (1,10).В R я бы использовал X [10,:, drop = F].Есть ли что-то похожее в NumPy.Я не смог найти его в документации и не увидел похожего вопроса.

Спасибо!

Ответы [ 6 ]

78 голосов
/ 12 августа 2013

Другое решение - сделать

X[[10],:]

или

I = array([10])
X[I,:]

Размерность массива сохраняется, когда индексация выполняется списком (или массивом) индексов. Это хорошо, потому что у вас есть выбор между сохранением размера и сжатием.

46 голосов
/ 24 августа 2010

Вероятно, это проще всего сделать x[None, 10, :] или эквивалентно (но более читабельно) x[np.newaxis, 10, :].

Что касается того, почему это не по умолчанию, лично я нахожу, что постоянное наличие массивов с одноэлементными измерениями очень быстро раздражает. Я предполагаю, что тупые разработчики чувствовали то же самое.

Кроме того, широковещательные массивы очень хорошо обрабатываются, поэтому обычно нет особых причин сохранять размер массива, из которого получен фрагмент. Если вы сделали, то такие вещи, как:

a = np.zeros((100,100,10))
b = np.zeros(100,10)
a[0,:,:] = b

либо не сработает, либо будет гораздо сложнее реализовать.

(Или, по крайней мере, это мое предположение о том, что недоуменный разработчик объясняет необходимость отбрасывать размерную информацию при нарезке)

26 голосов
/ 24 августа 2010

Я нашел несколько разумных решений.

1) использовать numpy.take(X,[10],0)

2) использовать эту странную индексацию X[10:11:, :]

В идеале это должно быть по умолчанию,Я никогда не понимал, почему размеры упали.Но это обсуждение для NumPy ...

3 голосов
/ 19 марта 2019

Вот альтернатива, которая мне нравится больше.Вместо индексации одним числом, индекс с диапазоном.То есть используйте X[10:11,:].(Обратите внимание, что 10:11 не включает 11).

import numpy as np
X = np.zeros((100,10))
X.shape        # >> (100, 10)
xslice = X[10:11,:]
xslice.shape   # >> (1,10)

Это также облегчает понимание с большим количеством измерений, без None жонглирования и определения, какую ось использовать, какой индекс.Также нет необходимости делать дополнительную бухгалтерию относительно размера массива, просто i:i+1 для любых i, которые вы использовали бы при обычной индексации.

b = np.ones((2, 3, 4))
b.shape # >> (2, 3, 4)
b[1:2,:,:].shape  # >> (1, 3, 4)
b[:, 2:3, :].shape .  # >> (2, 1, 4)
1 голос
/ 20 марта 2019

Чтобы добавить к решение, включающее индексирование по спискам или массивам по gnebehay, также можно использовать кортежи:

X[(10,),:]
0 голосов
/ 16 апреля 2019

Это особенно раздражает, если вы индексируете массив, который может иметь длину 1 во время выполнения. Для этого случая есть np.ix_:

some_array[np.ix_(row_index,column_index)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...