Подтвердить что ты не робот

Нисходящий индексный сегмент без потери информации об измерении

Я использую 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. Я не мог найти его в документации и не видел подобного вопроса.

Спасибо!

4b9b3361

Ответ 1

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

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

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

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

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

(Или, по крайней мере, мое предположение о том, что numpy dev рассуждает о снижении информации о размере при разрезании)

Ответ 2

Другим решением является

X[[10],:]

или

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

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

Ответ 3

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

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

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

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

Ответ 4

Здесь альтернатива мне нравится больше. Вместо индексации одним числом, индекс с диапазоном. То есть используйте 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)

Ответ 6

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

some_array[np.ix_(row_index,column_index)]