Удобный для памяти способ добавить поле в структурированный ndarray - без дублирования данных?

1

Чтобы добавить поле в структурированный массив numpy, достаточно просто создать новый массив с новым dtype, скопировать поверх старых полей и добавить новое поле. Тем не менее, мне нужно сделать это для массива, который занимает много памяти, и я бы предпочел не дублировать его все. И моя собственная реализация, и медленная реализация в дублирующей памяти numpy.lib.recfunctions.append_fields.

Есть ли способ добавить поле к структурированному ndarray, не дублируя память? Это означает, что это позволяет избежать создания нового ndarray или способа создания нового ndarray, который указывает на те же данные, что и старый?

Решения, дублирующие оперативную память:

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

  • 0
    Если ваш массив представляет собой представление в буфере, последняя половина которого не используется, вы можете выделить дополнительные поля в последней половине (а не рядом с их существующей строкой).
Теги:
arrays
numpy
memory
structured-array

1 ответ

3
Лучший ответ

Структурированный массив хранится, как обычный, как непрерывный буфер байтов, по одной записи, следующей за предыдущей. Записи, таким образом, немного похожи на последнее измерение многомерного массива. Вы не можете добавить столбец в массив 2d, не создавая новый массив через конкатенацию.

Добавление поля, например I4 dtype в dtype, которое, скажем, длиной 20 байт, означает изменение длины записи (элемента) до 24, то есть добавление 4 байта в буфер каждые 20 байт. numpy не может этого сделать, не создавая новый буфер данных и не копируя значения из старого (и нового).

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

Поля в структурированном массиве не похожи на объекты в списке или словаре. Вы не можете добавить поле, просто добавив указатель на объект в другом месте в памяти.

Возможно, вы должны использовать словарь, а item - массив. Затем вы можете свободно добавлять ключ/элемент без копирования существующих. Но тогда доступ к "строкам" будет медленным.

  • 0
    Хмм хорошо. Мне нужен другой подход тогда. Возможно, я мог бы разрезать большой массив на N частей, добавляя поля к меньшим частям по одному, так, чтобы я все еще копировал все, но не все сразу, таким образом ограничивая пиковое использование памяти.
  • 0
    Тем не менее, должно быть возможно сделать это удобным для памяти способом, не дублируя данные. Он может копировать данные в новый массив и увеличивать новый размер массива, одновременно уменьшая старый размер массива.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню