2016-10-10 13 views
1

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

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

Решения, которые делают дубликат RAM:

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

+0

Если ваш массив представляет собой представление в буфере, последнее из которого не используется, вы можете выделить дополнительные поля в последней половине (а не смежные с их существующей строкой). – Eric

ответ

3

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

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

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

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

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

+0

Хм, хорошо. Тогда мне нужен другой подход. Возможно, я мог бы вырезать большой массив из N штук, добавляя поля к меньшим частям по одному, чтобы я все еще копировал все, но не сразу, что ограничивало использование пиковой памяти. – gerrit

+0

Тем не менее, это должно быть возможно сделать это в удобной для памяти форме без дублирования данных. Он может копировать данные в новый массив и увеличивать размер нового массива, одновременно уменьшая размер старого массива. – Bastiaan

+0

Для каждого «роста» и «уменьшения» требуется копия данных.Не беспокойтесь о «дружественной памяти», если это действительно не повредит время выполнения или проблемы с ошибкой памяти. Но не сталкивайтесь с этими двумя проблемами. – hpaulj