Как NumPy View узнает, где значения, на которые он ссылается, находятся в исходном NUMPY массиве? - PullRequest
0 голосов
/ 16 декабря 2018

Насколько я понимаю, массив numpy - это объект, хранящий значения в непрерывном блоке памяти, в то время как встроенные контейнеры Python (list, tuple, set, dict) содержат ссылки на объекты.Обычная нарезка массива numpy возвращает представление, содержащее указанное подмножество этих значений.

На поверхности представление выглядит как другой массив numpy (тип (aView) возвращает numpy.ndarray), но его значения не являютсякопии, а скорее те же значения, что и у исходного массива;изменение значений представления на месте также изменяет значения исходного массива.

Как вид делает это?Я полагаю, что представление должно содержать какие-то указатели на значения в исходном массиве, но пара вещей дает мне паузу:

  1. Значения в массиве не являются объектами, иЯ не знаю, как можно сделать ссылки на маленькие кусочки одного и того же объекта.

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

1 Ответ

0 голосов
/ 16 декабря 2018

Массив NumPy знает свой базовый адрес, тип данных, форму и шаг.Большинству приложений не нужно явно иметь дело с шагами, но именно они делают некоторые из этих работ.Пошаговые инструкции показывают, сколько байтов необходимо добавить, чтобы увеличить заданное измерение на одну логическую единицу (например, строку).

Если вы начинаете с массива float64 размером 3x3 (он же f8) по адресу 0x1000, и выВы хотите просмотреть подрешетку 2x2, которая начинается в центре оригинала, все, что вам нужно, это увеличить базовый адрес на 4 элемента (3 для всего первого ряда, 1 для перемещения слева в центр среднего ряда)и помните, что каждая строка начинается через 24 байта после предыдущей (несмотря на то, что она имеет длину всего 16 байтов).

Концептуально мы идем от этого:

base=0x1000
shape=(3,3)
strides=(24,8)
dtype='f8'

К этому:

base=0x1020 (added 1*24 + 1*8 for [1:,1:] view)
shape=(2,2)
strides=(24,8)
dtype='f8'

И представление принимает следующие элементы:

. . .
. 4 5
. 7 8

Некоторые флаги настраиваются в представлении, такие как флаг C_CONTIGUOUS, который необходимо сбросить, поскольку представление больше не является непрерывной областью.

Strides поддерживает не только представления массивов NumPy, но также представления структур данных, которые не были созданы в NumPy.Например, если у вас есть массив структур C, и первый элемент каждого из них представляет собой точку (x,y), вы можете построить представление только этих точек, установив шаг по размеру всей структуры, несмотря на то, что dtype является простодва числа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...