Усечение большого массива (A = A [: N]) - очищается ли исходный A?Могу ли я «избавиться» от A [: N] .base и «передать право собственности»? - PullRequest
0 голосов
/ 04 декабря 2018

Предположим, у меня большой массив:

A = numpy.arange(100000000)

, и теперь я его усекаю:

A = A[:10]

Раньше я думал, что, учитывая, что у меня нет именипривязанный к оригиналу A, его счетчик ссылок упал до нуля, и он будет собирать мусор.Тем не менее, A.base тайно все еще относится к исходному массиву!Означает ли это, что единственный способ прояснить это - сделать явную копию, т.е.

A = A[:10].copy()

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

(удаленно связанный вопрос: Эффективный для памяти способ усечения большого массива в Matlab )

Ответы [ 2 ]

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

Когда вы делаете это:

A = A[:10]

Вы возвращаете представление исходного A (потому что это индексирование срезов), а не создаете новый массив.Таким образом, оригинал A не освобождается, потому что он вам все еще нужен.

Правильный способ действительно заключается в создании копии, либо с помощью:

A = A[:10].copy()

Или:

A = np.array(A[:10])
0 голосов
/ 04 декабря 2018

За документация :

Все массивы, сгенерированные базовой секцией, всегда просмотров исходного массива.

Итак, представьте, что ваша A - фотография Моны Лизы.И вы устанавливаете рамку перед ней, чтобы она содержала только голову Моны Лизы (если смотреть под правильным углом).Если кто-то уберет Мону Лизу, «картина» головы Моны Лизы перед ней также исчезнет.Вам нужно скопировать то, что вы видите в маленькой рамке, на новый холст, чтобы иметь копию, которая была бы безопасна от удаления оригинала.

Вы можете проверить это:

A = numpy.arange(100000000)
B = A[:10]
B[0] = 17
A[:5]
# => [17, 1, 2, 3, 4]

Так что вам абсолютно необходимо скопировать, чтобы отделить ваш новый массив от исходного массива.Вы можете создать копию различными способами.Один явно с copy, или с array конструктором.Вы также можете использовать расширенную нарезку, которая не возвращает представление:

B = A[range(10)]
B[1] = 34
A[:5]
# => array([17,  1,  2,  3,  4])
B[:5]
# => array([17, 34,  2,  3,  4])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...