sys.getdizeof 메소드와 NumPy배열의 nbytes 속성을 사용하여 Numpy 배열의 크기를 확인해봤습니다.
2022. 01. 22 최초작성
동적으로 크기를 늘릴 수 있는 Python의 리스트와 달리 NumPy 배열을 생성하면 고정된 크기를 갖습니다.
또한 여러가지 데이터 타입의 원소를 가질 수 있는 Python의 리스트와 달리 NumPy 배열의 모든 원소는 동일한 데이터 타입이어야 합니다.
따라서 메모리 상에 저장된 NumPy 배열의 원소들의 크기는 모두 동일합니다.
NumPy 배열에 여러가지 데이터 타입의 값을 넣어보면 에러가 나지 않지만 NumPy 배열의 데이터 타입을 확인해보면 원소들을 모두 포함할 수 있는 데이터 타입으로 되어 있는 것을 볼 수 있습니다.
>>> a = np.array([1, 'hello', 0.1])
>>> a
array(['1', 'hello', '0.1'], dtype='<U32')
데이터 타입으로 지정된 <U32의 의미는 32개의 문자로 구성된 리틀 엔디안 유니코드 문자열이라는 의미입니다. 자세한 내용은 링크
https://stackoverflow.com/a/56944839 를 확인하세요.
NumPy 배열의 nbytes 속성은 저장된 데이터의 크기를 반환하고 sys.getsizeof 메소드는 오버헤드(overhead)가 포함된 NumPy 배열의 전체 크기를 반환합니다. 오버헤드는 NumPy 배열에 저장된 데이터를 위한 정보(배열 차원, 데이터 타입 등) 때문입니다. NumPy 배열이 클래스이기 때문에 추가되는 정보도 더 있을거라 예상됩니다. 원소가 없는 비어있는 넘파이 배열을 getsizeof로 확인해보면 할당된 메모리가 있는데 이것이 오버헤드를 위한 것입니다.
NumPy 배열에 원소가 추가되면 비어있는 넘파이 배열에 할당된 크기에 추가된 원소 개수 * 원소 타입 크기만큼 메모리가 추가됩니다. 넘파이 배열이 커져도 비어있는 넘파이 배열에 할당되었던 크기는 유지됩니다.
NumPy 배열의 nbytes 속성과 sys.getsizeof 메소드를 테스트한 코드입니다.
import sys import numpy as np numpy_array_empty = np.array([]) numpy_array_empty_float32 = np.array([], dtype=np.float32) numpy_array_empty_int8 = np.array([], dtype=np.int8) numpy_array_one = np.array([3]) numpy_array_one_float32 = np.array([3], dtype=np.float32) numpy_array_one_int8 = np.array([3], dtype=np.int8) numpy_array_10 = np.arange(10) numpy_array_10_int8 = np.arange(10, dtype=np.int8) print("numpy_array_empty (", numpy_array_empty.dtype, ") -> ", "nbytes", numpy_array_empty.nbytes, "getsizeof", sys.getsizeof(numpy_array_empty)) print("numpy_array_empty_float32 (", numpy_array_empty_float32.dtype, ") -> ", "nbytes", numpy_array_empty_float32.nbytes, "getsizeof", sys.getsizeof(numpy_array_empty_float32)) print("numpy_array_empty_int8 (", numpy_array_empty_int8.dtype, ") -> ", "nbytes", numpy_array_empty_int8.nbytes, "getsizeof", sys.getsizeof(numpy_array_empty_int8)) print("numpy_array_one (", numpy_array_one.dtype, ") -> ", "nbytes", numpy_array_one.nbytes, "getsizeof", sys.getsizeof(numpy_array_one), "diff", sys.getsizeof(numpy_array_one)-sys.getsizeof(numpy_array_empty)) print("numpy_array_one_float32 (", numpy_array_one_float32.dtype, ") -> ", "nbytes", numpy_array_one_float32.nbytes, "getsizeof", sys.getsizeof(numpy_array_one_float32), "diff", sys.getsizeof(numpy_array_one_float32)-sys.getsizeof(numpy_array_empty_float32)) print("numpy_array_one_int8 (", numpy_array_one_int8.dtype, ") -> ", "nbytes", numpy_array_one_int8.nbytes, "getsizeof", sys.getsizeof(numpy_array_one_int8), "diff", sys.getsizeof(numpy_array_one_int8)-sys.getsizeof(numpy_array_empty_int8)) print("numpy_array_10 (", numpy_array_10.dtype, ") -> ", "nbytes", numpy_array_10.nbytes, "getsizeof", sys.getsizeof(numpy_array_10), "diff", sys.getsizeof(numpy_array_10)-sys.getsizeof(numpy_array_empty)) print("numpy_array_10_int8 (", numpy_array_10_int8.dtype, ") -> ", "nbytes", numpy_array_10_int8.nbytes, "getsizeof", sys.getsizeof(numpy_array_10_int8), "diff", sys.getsizeof(numpy_array_10_int8)-sys.getsizeof(numpy_array_empty_int8)) # numpy_array_empty ( float64 ) -> nbytes 0 getsizeof 104 # numpy_array_empty_float32 ( float32 ) -> nbytes 0 getsizeof 104 # numpy_array_empty_int8 ( int8 ) -> nbytes 0 getsizeof 104 # numpy_array_one ( int64 ) -> nbytes 8 getsizeof 112 diff 8 # numpy_array_one_float32 ( float32 ) -> nbytes 4 getsizeof 108 diff 4 # numpy_array_one_int8 ( int8 ) -> nbytes 1 getsizeof 105 diff 1 # numpy_array_10 ( int64 ) -> nbytes 80 getsizeof 184 diff 80 # numpy_array_10_int8 ( int8 ) -> nbytes 10 getsizeof 114 diff 10 |
실행 결과를 살펴보겠습니다.
사용한 운영체제 또는 Python 버전 등에 따라 포스트의 결과와 다를 수 있습니다.
포스트에서 사용한 환경은 다음과 같습니다.
macOS Monterey 12.1
Python 3.8.11 64bit
NumPy 1.21.4
비어있는 NumPy 배열의 경우 nbytes 속성값은 0 바이트 , sys.getsizeof 메소드의 값은 104 바이트로 동일합니다.
numpy_array_empty ( float64 ) -> nbytes 0 getsizeof 104
numpy_array_empty_float32 ( float32 ) -> nbytes 0 getsizeof 104
numpy_array_empty_int8 ( int8 ) -> nbytes 0 getsizeof 104
원소를 하나씩 추가해보면 추가한 원소의 데이터 타입 크기 만큼 바이트 수가 증가합니다.
numpy_array_one ( int64 ) -> nbytes 8 getsizeof 112 diff 8
numpy_array_one_float32 ( float32 ) -> nbytes 4 getsizeof 108 diff 4
numpy_array_one_int8 ( int8 ) -> nbytes 1 getsizeof 105 diff 1
원소를 10개씩 추가해보면 추가한 원소의 데이터 타입 크기 * 10 만큼 바이트 수가 증가합니다.
numpy_array_10 ( int64 ) -> nbytes 80 getsizeof 184 diff 80
numpy_array_10_int8 ( int8 ) -> nbytes 10 getsizeof 114 diff 10
참고
https://community.dataquest.io/t/ndarray-nbytes-vs-sys-getsizeof-ndarray/547939
https://stackoverflow.com/questions/35421869/nbytes-and-getsizeof-return-different-values
https://www.reddit.com/r/learnpython/comments/9cp9id/understanding_memory_in_python/
'Python > Numpy' 카테고리의 다른 글
두 개의 넘파이 배열을 같은 순서로 정렬하기 (0) | 2023.10.21 |
---|---|
Numpy Array 이미지를 하나의 Numpy Array로 합쳤다가 분리하기 (0) | 2022.12.08 |
Python 예제 - Numpy 배열에 열 추가하기 (0) | 2021.12.01 |
Python 예제 - Numpy 배열에서 0이 아닌 최소값 찾기 (0) | 2021.12.01 |
Python List의 append와 Numpy 배열의 append 비교 (0) | 2021.11.29 |
시간날때마다 틈틈이 이것저것 해보며 블로그에 글을 남깁니다.
블로그의 문서는 종종 최신 버전으로 업데이트됩니다.
여유 시간이 날때 진행하는 거라 언제 진행될지는 알 수 없습니다.
영화,책, 생각등을 올리는 블로그도 운영하고 있습니다.
https://freewriting2024.tistory.com
제가 쓴 책도 한번 검토해보세요 ^^
그렇게 천천히 걸으면서도 그렇게 빨리 앞으로 나갈 수 있다는 건.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!