numpy 배열의 파이썬 메모리 사용


156

파이썬을 사용하여 큰 파일을 분석하고 메모리 문제가 발생하고 있으므로 sys.getsizeof ()를 사용하여 사용량을 추적하려고 시도했지만 사용량이 많은 배열의 동작은 기괴합니다. 다음은 내가 열어야 할 알베도 스 맵과 관련된 예입니다.

>>> import numpy as np
>>> import struct
>>> from sys import getsizeof
>>> f = open('Albedo_map.assoc', 'rb')
>>> getsizeof(f)
144
>>> albedo = struct.unpack('%df' % (7200*3600), f.read(7200*3600*4))
>>> getsizeof(albedo)
207360056
>>> albedo = np.array(albedo).reshape(3600,7200)
>>> getsizeof(albedo)
80

데이터는 여전히 존재하지만 3600x7200 픽셀 맵인 객체의 크기는 ~ 200Mb에서 80 바이트로 줄었습니다. 메모리 문제가 끝나고 모든 것을 numpy 배열로 변환하기를 희망하지만이 행동이 사실이라면 어떤 식 으로든 정보 이론이나 열역학 또는 무언가를 위반 할 것이라고 생각합니다. getsizeof ()는 numpy 배열에서 작동하지 않는다고 생각했습니다. 어떤 아이디어?


8
문서에서 sys.getsizeof: "바이트 단위로 객체의 크기를 반환합니다. 객체는 모든 유형의 객체가 될 수 있습니다. 모든 내장 객체는 올바른 결과를 반환하지만 타사 확장명을 그대로 유지할 필요는 없습니다. "구체적으로 직접 메모리에 기여하는 메모리 소비 만 설명하고, 오브젝트가 참조하는 메모리 소비는 설명하지 않습니다."
Joel Cornett

1
이로 인해 특히 타사 확장 getsizeof의 경우 메모리 소비에 대한 신뢰할 수없는 지표가됩니다 .
Joel Cornett

13
기본적으로 여기서 문제 는 새 배열이 아닌을 resize반환 한다는 것 입니다 view. 실제 데이터가 아닌 뷰의 크기를 얻습니다.
mgilson

이를 sys.getsizeof(albedo.base)위해 비보기의 크기를 제공합니다.
에릭

답변:


236

array.nbytesnumpy 배열에 사용할 수 있습니다 ( 예 :

>>> import numpy as np
>>> from sys import getsizeof
>>> a = [0] * 1024
>>> b = np.array(a)
>>> getsizeof(a)
8264
>>> b.nbytes
8192

가져 오기 sys를 수행 한 후 sys.getsizeof (a).
eddys

2
b.__sizeof__()에 해당sys.getsizeof(b)
palash

1
round(getsizeof(a) / 1024 / 1024,2)MB를 얻으려면
gies0r

13

nbytes 필드 는 배열의 모든 요소의 크기를 바이트 단위로 표시합니다 numpy.array.

size_in_bytes = my_numpy_array.nbytes

이것은 "배열 객체의 비 요소 속성"을 측정하지 않으므로 실제 크기 (바이트)는 이보다 몇 바이트 더 클 수 있습니다.


이 답변은 여전히 ​​배열을 생성하므로 "목록에서 배열로 변환 할 필요가 없음"을 의미한다고 생각합니다. OP가 이미 배열을 가지고 있기 때문에 GWW의 답변이 먼저 목록을 생성 한 다음 배열로 변환하는 것이 사실이지만, 요점은 numpy 배열의 크기를 얻는 방법이므로 그렇지 않습니다. 처음에 어레이를 얻는 방법에 대해 중요합니다. 기존 배열을 재구성한다고 말 함으로써이 대답을 비판 할 수 있습니다.
Moot

@Moot 님, 댓글 주셔서 감사합니다. 문제는 배열의 크기를 바이트 단위로 얻는 방법에 관한 것입니다. 내 스 니펫이 먼저 배열을 생성한다는 것은 사실이지만 실행 가능한 완전한 예제를 제공하기위한 것입니다. 나는 이것을 강조하기 위해 대답을 편집 할 것입니다.
El Marce

1

파이썬 노트북에서 나는 종종 '매달려'필터링 할 numpy.ndarray의, 특히에 저장되어있는 사람 _1, _2정말 의미하지 않았다 등이 살아 남기 위해.

이 코드를 사용하여 모든 코드와 크기 목록을 가져옵니다.

locals()또는 globals()더 나은지 확실하지 않습니다 .

import sys
import numpy
from humanize import naturalsize

for size, name in sorted(
    (value.nbytes, name)
    for name, value in locals().items()
    if isinstance(value, numpy.ndarray)):
  print("{:>30}: {:>8}".format(name, naturalsize(size)))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.