[python] Pandas의 DataFrame에 필요한 메모리 양을 추정하는 방법은 무엇입니까?

궁금한 점이 있습니다 … 400MB csv 파일을 pandas 데이터 프레임 (read_csv 또는 read_table 사용)으로 읽는 경우 필요한 메모리 양을 추측 할 수있는 방법이 있습니까? 데이터 프레임과 메모리에 대한 더 나은 느낌을 얻으려는 것뿐입니다.



답변

df.memory_usage() 각 열이 차지하는 양을 반환합니다.

>>> df.memory_usage()

Row_ID            20906600
Household_ID      20906600
Vehicle           20906600
Calendar_Year     20906600
Model_Year        20906600
...

인덱스를 포함하려면 index=True.

따라서 전체 메모리 사용량을 얻으려면 :

>>> df.memory_usage(index=True).sum()
731731000

또한 전달 deep=True하면 포함 된 개체의 전체 사용량을 설명하는보다 정확한 메모리 사용량 보고서를 사용할 수 있습니다.

이는 메모리 사용량에 배열의 구성 요소가 아닌 요소가 사용하는 메모리가 포함되지 않기 때문입니다 deep=False(기본값).


답변

다음은 다른 방법의 비교입니다 sys.getsizeof(df). 가장 간단합니다.

이 예에서는 df814 개의 행, 11 개의 열 (2 개의 정수, 9 개의 개체)이있는 데이터 프레임입니다. 427kb shapefile에서 읽습니다.

sys.getsizeof (df)

>>> 시스템 가져 오기
>>> sys.getsizeof (df)
(결과를 바이트로 제공)
462456

df.memory_usage ()

>>> df.memory_usage ()
...
(각 열을 8 바이트 / 행으로 나열)

>>> df.memory_usage (). sum ()
71712
(대략 행 * 열 * 8 바이트)

>>> df.memory_usage (deep = True)
(각 열의 전체 메모리 사용량 나열)

>>> df.memory_usage (deep = True) .sum ()
(결과를 바이트로 제공)
462432

df.info ()

데이터 프레임 정보를 표준 출력으로 인쇄합니다. 기술적으로는 킬로바이트가 아니라 킬로바이트 (KiB)입니다. 독 스트링에서 “메모리 사용량은 사람이 읽을 수있는 단위 (base-2 표현)로 표시됩니다.”라고 말합니다. 따라서 바이트를 얻으려면 1024를 곱해야합니다 (예 : 451.6 KiB = 462,438 바이트).

>>> df.info ()
...
메모리 사용량 : 70.0+ KB

>>> df.info (memory_usage = 'deep')
...
메모리 사용량 : 451.6KB


답변

나는 토론에 더 많은 데이터를 가져올 것이라고 생각했습니다.

이 문제에 대해 일련의 테스트를 실행했습니다.

파이썬 resource패키지를 사용하여 내 프로세스의 메모리 사용량을 얻었습니다.

그리고 csv를 StringIO버퍼 에 쓰면 그 크기를 바이트 단위로 쉽게 측정 할 수 있습니다.

저는 두 번의 실험을 실행했습니다. 각 실험은 10,000 줄에서 1,000,000 줄 사이에서 크기가 증가하는 20 개의 데이터 프레임을 생성했습니다. 둘 다 10 개의 열이 있습니다.

첫 번째 실험에서는 데이터 세트에서 부동 소수점 만 사용했습니다.

이것은 행 수의 함수로서 csv 파일에 비해 메모리가 증가한 방식입니다. (메가 바이트 단위의 크기)

부동 항목이있는 행 수에 따른 메모리 및 CSV 크기 (MB)

두 번째 실험은 동일한 접근 방식을 사용했지만 데이터 세트의 데이터는 짧은 문자열로만 구성되었습니다.

문자열 항목이있는 행 수에 따른 메모리 및 CSV 크기 (MB)

csv 크기와 데이터 프레임 크기의 관계는 상당히 다를 수 있지만 메모리 크기는 항상 2 ~ 3 배 더 커질 것입니다 (이 실험의 프레임 크기).

더 많은 실험을 통해이 답변을 완료하고 싶습니다. 특별한 것을 시도해보고 싶다면 의견을 보내주십시오.


답변

역순으로해야합니다.

In [4]: DataFrame(randn(1000000,20)).to_csv('test.csv')

In [5]: !ls -ltr test.csv
-rw-rw-r-- 1 users 399508276 Aug  6 16:55 test.csv

기술적으로 메모리는 이것에 관한 것입니다 (인덱스 포함)

In [16]: df.values.nbytes + df.index.nbytes + df.columns.nbytes
Out[16]: 168000160

따라서 메모리에 168MB, 400MB 파일, 1M 행, 20 개의 부동 열

DataFrame(randn(1000000,20)).to_hdf('test.h5','df')

!ls -ltr test.h5
-rw-rw-r-- 1 users 168073944 Aug  6 16:57 test.h5

바이너리 HDF5 파일로 작성할 때 훨씬 더 압축

In [12]: DataFrame(randn(1000000,20)).to_hdf('test.h5','df',complevel=9,complib='blosc')

In [13]: !ls -ltr test.h5
-rw-rw-r-- 1 users 154727012 Aug  6 16:58 test.h5

데이터가 임의적이기 때문에 압축이별로 도움이되지 않습니다.


답변

dtype배열의 를 알고 있다면 데이터를 저장하는 데 필요한 바이트 수와 Python 객체 자체에 대한 일부를 직접 계산할 수 있습니다. numpy배열 의 유용한 속성은 입니다 nbytes. 다음 DataFrame을 수행 하여 팬더의 배열에서 바이트 수를 얻을 수 있습니다.

nbytes = sum(block.values.nbytes for block in df.blocks.values())

objectdtype 배열은 객체 당 8 바이트를 저장하므로 (객체 dtype 배열은 불투명에 대한 포인터를 저장합니다 PyObject), csv에 문자열이있는 경우 read_csv이를 objectdtype 배열 로 변환하고 그에 따라 계산을 조정 하는 것을 고려해야합니다.

편집하다:

에 대한 자세한 내용은 numpy스칼라 유형 페이지 를 참조하세요 object dtype. 참조 만 저장되기 때문에 배열에있는 객체의 크기도 고려해야합니다. 이 페이지에서 말했듯이 객체 배열은 Python list객체 와 다소 유사 합니다.


답변

네, 있습니다. Pandas는 데이터를 ndarraydtype별로 그룹화하여 2 차원 numpy 구조 에 저장합니다 . ndarray기본적으로 작은 헤더가있는 데이터의 원시 C 배열입니다. 따라서 dtype포함 된 크기 와 배열 의 크기를 곱하여 크기를 추정 할 수 있습니다 .

예 : 2 개 np.int32및 5 개 np.float64열 이있는 1000 개의 행이있는 경우 DataFrame은 하나의 2×1000 np.int32배열과 하나의 5×1000 np.float64배열을 갖게 됩니다.

4 바이트 * 2 * 1000 + 8 바이트 * 5 * 1000 = 48000 바이트


답변

이것은 파이썬의 모든 객체에 메모리 내 크기를 제공한다고 생각합니다. pandas 및 numpy와 관련하여 내부를 확인해야합니다.

>>> import sys
#assuming the dataframe to be df 
>>> sys.getsizeof(df)
59542497