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


125

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


항상 프로세스 및 단일 파일에 대한 메모리 사용량을 볼 수 있습니다. 당신이 리눅스를 실행하는 경우, 시도 top하고 Shift + M내 메모리 사용량을 정렬합니다.
JayQuerie.com 2013 년

공개 판다 문제를 광고해야한다고 생각합니다 .
Andy Hayden

3
4 백만 개의 행이있는 큰 데이터 프레임이 있습니다. 빈 하위 집합 을 계산하는 x=df.loc[[]]0.1몇 초가 걸리고 (0 개의 행을 추출하는 데) 더 나아가 원래 데이터 프레임과 마찬가지로 수백 메가 바이트의 메모리 가 필요 하다는 것을 발견했습니다 .
osa

팬더 리드 개발자 의 이전 게시물 에 대한 새 링크
saladi

답변:


97

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(기본값).


1
모든 열의 메모리 사용량의 합계가 실제로 메모리 사용량에 미치는 영향입니까? 더 많은 오버 헤드가있을 것이라고 상상할 수 있습니다.
firelynx 2015

14
당신은 정말 또한 원하는deep=True
SMCI

df.memory_usage ()의 합이 sys.getsizeof (df)와 같지 않습니다! 많은 오버 헤드가 있습니다. SMCI가 언급 한 바와 같이, 당신은 필요deep=True
방랑

11
참고로, memory_usage()메모리 사용량을 바이트 단위로 반환합니다 (예상대로).
engelen

2
왜 deep = True의 유무와 큰 차이가 있습니까?
Nguai al

83

다음은 다른 방법의 비교입니다 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

g 위 코드 는 어떤 개체 또는 모듈을 참조합니까?
zozo

@zozo woops-오타 였음-수정 됨
Brian Burns

2
를 사용 df.info(memory_usage="deep")하면 "392.6MB"를 반환 sys.getsizeof(df)하고 df.memory_usage(index=True, deep=True).sum()둘 다 약 "411718016"(~ 411MB)을 반환합니다. 3 개의 결과가 일치하지 않는 이유를 설명해 주시겠습니까? 감사합니다
Catbuilts

2
@BrianBurns : df.memory_usage(deep=True).sum()거의 동일 돌아갑니다 df.memory_usage(index=True, deep=True).sum(). 제 경우에는 index메모리를 많이 사용하지 않습니다. 흥미롭게도, 그 발견 411718016/1024/1024 = 392.6, 그래서 df.info(memory_usage="deep")사용할 수 있습니다 2^10변환에 바이트MB 저를 혼동한다. 어쨌든 당신의 도움에 감사드립니다 : D.
Catbuilts

1
@Catbuilts 아, 설명합니다! df.info메가 바이트 (10 ^ 6)가 아닌 메비 바이트 (2 ^ 10)를 반환하고 있습니다. 답을 수정합니다.
Brian Burns

43

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

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

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

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

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

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

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

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

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

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

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

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


Y 축은 무엇입니까?
Ilya V. Schurov

1
디스크의 max_rss 및 csv 크기 (MB)
firelynx

31

역순으로해야합니다.

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

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


그것은 매우 영리합니다! 사용하여 파일을 읽는 데 필요한 메모리를 측정하는 방법에 대한 아이디어가 read_csv있습니까?
Andy Hayden

읽은대로 측정하는 방법을 모릅니다. IIRC 데이터를 저장하는 데 필요한 최종 메모리의 최대 2 배가 될 수 있습니다 (wes의 기사에서).하지만 그는 그것을 상수 + 최종 메모리로 가져 왔다고 생각합니다
Jeff

아, 다시 읽을 필요가 있습니다. 2x가 특정 알고리즘에 대해 편리한 이론적 분이라는 것을 기억했습니다.
Andy Hayden

(실시간으로) IO 성능을보기 위해 / iotop와 같이 사용할 수 있습니다 . tophtop
Phillip Cloud

1
nbytes예를 들어 데이터 프레임에 문자열이 있으면 과소 평가됩니다.
OSA

10

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객체 와 다소 유사 합니다.


감사합니다 Phillip! 명확히하기 위해-문자열의 경우 문자열 개체에 대한 포인터에 8 바이트와 실제 문자열 개체가 필요합니까?
Anne

1
예, 모든 객체 유형에 대해 8 바이트 포인터 + 크기 (객체)가 필요합니다
Viktor Kerkez 2013 년

1
그것은 df.blocks 모양) (df.blocks.values 제안하는 것은 지금 DICT이다
MRocklin

8

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

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

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


@AndyHayden 건설 비용은 무엇을 의미합니까? 의 인스턴스 크기 DataFrame?
Phillip Cloud

감사합니다 Victor! @Andy-건설 비용이 얼마나 큰지 아십니까?
Anne

포함되어 있지는 않지만 Cython에서 pandas매우 효율적인 구현 read_table이 있으므로 (numpy의 loadtxt보다 훨씬 낫습니다) 데이터를 파싱하고 ndarray.
Viktor Kerkez 2013-08-06

메모리를 필요 당신이 그것을 구축해야 @PhillipCloud은 .. 내가 언급되는 두 배의 크기를 기억하는 것 ...?
앤디 헤이든

6

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

>>> import sys
#assuming the dataframe to be df 
>>> sys.getsizeof(df) 
59542497
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.