Как сохранить ориентацию строк и столбцов векторов в numpy?

Исходя из фона Matlab/Octave, я пытался узнать numpy. Одна вещь, которая снова меня отключила, - это различие между векторами и многомерными массивами. По этому вопросу я дам конкретную проблему, которую я имею, но я был бы очень обязан, если бы кто-то мог объяснить более общую картину за одномерными массивами в numpy, почему вы хотели бы их в первую очередь, как во избежание проблем при смешивании одиночных и многомерных массивов и т.д. В любом случае вопрос:

У меня есть 2-D массив, называемый X:

X = numpy.arange(10).reshape(2,5)

и я хочу взять последний столбец X и сохранить его как еще один двухмерный массив (т.е. вектор-столбец), который называется Y. Единственный способ, с которым я смог справиться, это:

Y = numpy.atleast_2d(X[:,4]).T

но мне это не нравится по нескольким причинам:

  • Я не чувствую, что мне нужно было бы это передать транспонировать вектор, когда ориентация должна подразумеваться в X [:, 4].

  • Использование atleast_2D кажется слишком громоздким для использования снова и снова в коде, где эта ситуация может возникнуть много. Мне кажется, что я делаю что-то неправильно.

Итак, короче, есть ли лучший способ?

Спасибо.

Ответы

Ответ 1

Во-первых, простой способ сделать то, что вы хотите:

Y = X[:,4:]

Теперь причина, по которой numpy не делала этого, когда вы пытались это сделать, связана с тем, как массивы работают на Python и фактически на большинстве языков программирования. Когда вы пишете что-то вроде a[4], которое обращается к пятому элементу массива, не дает вам представление о какой-либо части исходного массива. Так, например, если a - это массив чисел, то a[4] будет просто числом. Если a является двумерным массивом, то есть эффективно массивом массивов, то a[4] будет одномерным массивом. В принципе, операция доступа к элементу массива возвращает что-то с размерностью, меньшей, чем исходный массив.

Теперь Python включает в себя эту вещь, называемую "нотой среза", представленную с использованием двоеточия, которая представляет собой другой способ доступа к элементам массива. Вместо того, чтобы возвращать элемент (что-то с размерностью одного меньше исходного массива), он возвращает копию раздела исходного массива. По существу, a:b представляет список всех элементов с индексами a (включительно) до b (исключительный). Либо a, либо b, либо оба могут быть опущены, и в этом случае срез проходит до соответствующего конца массива.

Что это означает для вашего случая, так это то, что когда вы пишете X[:,4], у вас есть одна нотация фрагмента и одна стандартная нотация индекса. Обозначение среза представляет все индексы вдоль первого измерения (только 0 и 1, так как массив имеет две строки), а 4 представляет пятый элемент вдоль второго измерения. Каждый экземпляр регулярного индекса в основном уменьшает размерность возвращаемого объекта на единицу, так как X является двумерным массивом, и есть один регулярный индекс, вы получаете результат 1D. Numpy просто отображает 1D массивы в виде векторов строк. Трюк, если вы хотите получить что-то из того же размера, с которого вы начали, заключается в том, чтобы использовать все индексы среза, как это было в примере в верхней части этого сообщения.

Если вы хотите извлечь пятый столбец из того, что имело более 5 полных столбцов, вы можете использовать X[:,4:5]. Если вы хотите просмотреть строки 3-4 и столбцы 5-7, вы должны сделать X[3:5,5:8]. Надеюсь, вы получите эту идею.