모양 및 데이터 유형으로 배열을 할당할 수 없습니다.
저는 Ubuntu 18에서 거대한 어레이를 numpy로 할당하는 문제에 직면했지만 MacOS에서는 동일한 문제에 직면하지 않았습니다.
모양이 있는 numpy 배열에 메모리를 할당하려고 합니다.(156816, 36, 53806)
와 함께
np.zeros((156816, 36, 53806), dtype='uint8')
Ubuntu OS에서 오류가 발생하는 동안
>>> import numpy as np
>>> np.zeros((156816, 36, 53806), dtype='uint8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
numpy.core._exceptions.MemoryError: Unable to allocate array with shape (156816, 36, 53806) and data type uint8
MacOS에서는 사용할 수 없습니다.
>>> import numpy as np
>>> np.zeros((156816, 36, 53806), dtype='uint8')
array([[[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]],
[[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]],
[[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]],
...,
[[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]],
[[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]],
[[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]]], dtype=uint8)
는 어디선가 그것을 .np.zeros
어레이에 필요한 전체 메모리를 실제로 할당하는 것이 아니라 0이 아닌 요소에만 할당해야 합니다.Ubuntu 기계는 64gb의 메모리를 가지고 있지만, 내 MacBook Pro는 16gb밖에 가지고 있지 않습니다.
버전:
Ubuntu
os -> ubuntu mate 18
python -> 3.6.8
numpy -> 1.17.0
mac
os -> 10.14.6
python -> 3.6.4
numpy -> 1.17.0
PS: Google Colab에서도 실패했습니다.
이는 시스템의 오버 커밋 처리 모드 때문일 수 있습니다.
모드에서 "는"입니다.0
,
경험적 접근 오버 커밋 처리입니다.주소 공간의 명백한 오버 커밋이 거부됩니다.일반적인 시스템에 사용됩니다.따라서 스왑 사용량을 줄이기 위해 오버 커밋을 허용하면서 심각한 와일드 할당이 실패합니다.루트는 이 모드에서 약간 더 많은 메모리를 할당할 수 있습니다.기본값입니다.
사용된 정확한 휴리스틱은 여기서 잘 설명되지 않지만, 이 페이지에서는 커밋 휴리스틱보다 Linux에서 더 자세히 설명합니다.
를 실행하여 현재 오버 커밋 모드를 확인할 수 있습니다.
$ cat /proc/sys/vm/overcommit_memory
0
이 경우, 당신은 당신이 할당하는 것입니다.
>>> 156816 * 36 * 53806 / 1024.0**3
282.8939827680588
282GB의 커널은 제가 그렇게 많은 물리적 페이지를 여기에 커밋할 수 없다는 것을 분명히 잘 말하고 있으며 할당을 거부합니다.
루트로 실행하는 경우:
$ echo 1 > /proc/sys/vm/overcommit_memory
이렇게 하면 "항상 오버 커밋" 모드가 활성화되며, 시스템은 크기에 상관없이 할당할 수 있습니다(최소한 64비트 메모리 주소 지정 내).
RAM이 했습니다. 32GB RAM 장착기서직테접스했다니습트. 모드 사용 시0
는 또한 저또한는도 .MemoryError
하지만 그것을 다시 바꾼 후에.1
작동합니다.
>>> import numpy as np
>>> a = np.zeros((156816, 36, 53806), dtype='uint8')
>>> a.nbytes
303755101056
그런 다음 어레이 내의 모든 위치에 쓰기 작업을 수행할 수 있습니다. 그러면 시스템은 사용자가 해당 페이지에 명시적으로 쓸 때만 실제 페이지를 할당합니다.따라서 희소 어레이에 주의하여 사용할 수 있습니다.
Window에서도 같은 문제가 발생하여 이 솔루션을 발견했습니다.Windows(윈도우)에서 이 문제가 발생할 경우 해결책은 페이지 파일 크기를 늘리는 것이었습니다. 메모리 오버커밋 문제이기도 했습니다.
윈도우 8
- 키보드에서 Windows 키 + X를 누른 다음 팝업 메뉴에서 시스템을 클릭합니다.
- 고급 시스템 설정을 누르거나 클릭합니다.관리자 암호를 입력하거나 선택 사항을 확인하라는 메시지가 표시될 수 있습니다.
- 고급 탭의 성능에서 설정을 누르거나 클릭합니다.
- 고급 탭을 누르거나 클릭한 다음 가상 메모리에서 변경을 누르거나 클릭합니다.
- 모든 드라이브의 페이징 파일 크기를 자동으로 관리 확인란의 선택을 취소합니다.
- 드라이브 [볼륨 레이블]에서 변경할 페이징 파일이 들어 있는 드라이브를 누르거나 클릭합니다.
- 사용자 지정 크기를 누르거나 클릭하고 초기 크기(MB) 또는 최대 크기(MB) 상자에 새 크기(MB)를 입력하고 설정을 누르거나 클릭한 다음 확인을 누릅니다.
- 시스템 재부팅
윈도우 10
- Windows 키를 누릅니다.
- 시스템 속성 고급 입력
- 관리자 권한으로 실행을 클릭합니다.
- 성능에서 설정을 클릭합니다.
- 고급 탭을 선택합니다.
- 변경 선택...
- 모든 드라이브의 페이징 파일 크기 자동 관리 선택 취소
- 그런 다음 사용자 지정 크기를 선택하고 적절한 크기를 입력합니다.
- 설정을 누른 다음 확인을 누르고 가상 메모리, 성능 옵션 및 시스템 속성 대화 상자를 종료합니다.
- 시스템 재부팅
참고: 이 예에서는 시스템에 ~282GB의 메모리가 부족했지만, 이 경우에는 제대로 작동했습니다.
편집
페이지 파일 크기에 대한 권장 사항은 다음과 같습니다.
올바른 페이지 파일 크기를 계산하는 공식이 있습니다.초기 크기는 총 시스템 메모리의 1.5 x 1.5 x입니다.최대 크기는 초기 크기의 3배입니다.따라서 4GB(1GB = 1,024MB x 4 = 4,096MB)의 메모리가 있다고 가정해 보겠습니다.초기 크기는 1.5 x 4,096 = 6,440 MB이고 최대 크기는 3 x 6,165 = 18,432 MB입니다.
여기서 명심해야 할 몇 가지 사항:
그러나 컴퓨터에 고유할 수 있는 다른 중요 요소와 시스템 설정은 고려하지 않습니다.다시 한 번, Windows(윈도우)에서 다른 컴퓨터에서 작동하는 일부 임의 수식에 의존하는 대신 사용할 항목을 선택하도록 합니다.
또한:
페이지 파일 크기를 늘리면 Windows에서 불안정 및 충돌을 방지하는 데 도움이 될 수 있습니다.그러나 하드 드라이브 읽기/쓰기 시간은 데이터가 컴퓨터 메모리에 있을 때보다 훨씬 느립니다.페이지 파일이 크면 하드 드라이브에 추가 작업이 추가되어 다른 모든 작업 속도가 느려집니다.페이지 파일 크기는 메모리 부족 오류가 발생한 경우에만 증가해야 하며 임시 수정으로만 증가해야 합니다.더 나은 해결책은 컴퓨터에 더 많은 메모리를 추가하는 것입니다.
Windows에서도 이 문제를 발견했습니다.저의 해결책은 32비트에서 64비트 버전의 파이썬으로 전환하는 것이었습니다.실제로 32비트 CPU와 같은 32비트 소프트웨어는 최대 4GB의 RAM(2^32)을 처리할 수 있습니다.따라서 RAM이 4GB 이상인 경우 32비트 버전에서는 이를 활용할 수 없습니다.
64비트 버전의 Python(다운로드 페이지에서 x86-64로 표시된 버전)에서는 문제가 사라집니다.
당신은 인터프리터를 입력하여 당신이 어떤 버전을 가지고 있는지 확인할 수 있습니다.64비트 버전의 I에는 다음이 있습니다.Python 3.7.5rc1 (tags/v3.7.5rc1:4082f600a5, Oct 1 2019, 20:28:14) [MSC v.1916 64 bit (AMD64)]
여기서 [MSC v.1916 64비트(AMD64)]는 "64비트 파이썬"을 의미합니다.
출처:
내 경우, dtype 특성을 추가하면 배열의 dtype이 더 작은 유형(float64에서 uint8)으로 변경되어 Windows(64비트)에서 MemoryError를 발생시키지 않을 만큼 배열 크기가 줄어듭니다.
부터
mask = np.zeros(edges.shape)
로.
mask = np.zeros(edges.shape,dtype='uint8')
데이터 유형을 메모리 작업량이 적은 다른 유형으로 변경합니다.데이터 유형을 numpy.uint8로 변경합니다.
data['label'] = data['label'].astype(np.uint8)
저는 EC2의 도커 컨테이너에서 판다를 운영하는 것과 같은 문제에 직면했습니다.나는 메모리 할당 오버커밋을 허용하는 위의 해결책을 시도했습니다.sysctl -w vm.overcommit_memory=1
(자세한 내용은 여기에 있습니다.) 그러나 여전히 문제를 해결하지 못했습니다.
Ubuntu/EC2의 메모리 할당 내부를 더 깊이 파고들기보다는 DataFrame을 병렬화하는 옵션을 찾기 시작했고, Dask를 사용하는 것이 제 경우에 효과적이라는 것을 알게 되었습니다.
import dask.dataframe as dd
df = dd.read_csv('path_to_large_file.csv')
...
주행 거리는 다양할 수 있으며, Dask API는 판다/넘피와 매우 유사하지만 완전히 같지는 않습니다(예: 데이터를 사용하는 방법에 따라 일부 코드를 변경해야 할 수도 있습니다).
이미지 크기를 600x600(360K)으로 설정하려다 numpy에 문제가 생겨 메모리 사용량을 7배 줄인 224x224(~50k)로 줄이기로 했습니다.
X_set = np.array(X_set).reshape(-1 , 600 * 600 * 3)
지금은
X_set = np.array(X_set).reshape(-1 , 224 * 224 * 3)
이것이 도움이 되길 바랍니다.
from pandas_profiling import ProfileReport
prof = ProfileReport(df, minimal=True)
prof.to_file(output_file='output.html')
나를 위해 일했습니다.
언급URL : https://stackoverflow.com/questions/57507832/unable-to-allocate-array-with-shape-and-data-type
'programing' 카테고리의 다른 글
Oracle에서 유지 여부와 상관없이 파티션 분할 (0) | 2023.06.16 |
---|---|
.NET 4.5로 업그레이드한 후 iFrame 파서 오류 발생 (0) | 2023.06.16 |
R 세션에서 사용 가능한 메모리를 관리하는 방법 (0) | 2023.06.16 |
한 .R 파일에 모든 함수를 정의하고 다른 .R 파일에서 호출합니다.어떻게, 가능하다면요? (0) | 2023.06.16 |
Ruby: Ubuntu에 rmagick 설치하기 (0) | 2023.06.16 |