programing tip

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

itbloger 2020. 8. 19. 07:48
반응형

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

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

이는 메모리 사용량에 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 ()

데이터 프레임 정보를 stdout에 인쇄합니다. 기술적으로는 킬로바이트가 아니라 킬로바이트 (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 파일에 비해 메모리가 증가한 방법입니다. (메가 바이트 단위의 크기)

Memory and CSV size in Megabytes as a function of the number of rows with float entries

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

Memory and CSV size in Megabytes as a function of the number of rows with string entries

It seems that the relation of the size of the csv and the size of the dataframe can vary quite a lot, but the size in memory will always be bigger by a factor of 2-3 (for the frame sizes in this experiment)

I would love to complete this answer with more experiments, please comment if you want me to try something special.


You have to do this in reverse.

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

Technically memory is about this (which includes the indexes)

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

So 168MB in memory with a 400MB file, 1M rows of 20 float columns

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

MUCH more compact when written as a binary HDF5 file

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

The data was random, so compression doesn't help too much


If you know the dtypes of your array then you can directly compute the number of bytes that it will take to store your data + some for the Python objects themselves. A useful attribute of numpy arrays is nbytes. You can get the number of bytes from the arrays in a pandas DataFrame by doing

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

object dtype arrays store 8 bytes per object (object dtype arrays store a pointer to an opaque PyObject), so if you have strings in your csv you need to take into account that read_csv will turn those into object dtype arrays and adjust your calculations accordingly.

EDIT:

See the numpy scalar types page for more details on the object dtype. Since only a reference is stored you need to take into account the size of the object in the array as well. As that page says, object arrays are somewhat similar to Python list objects.


Yes there is. Pandas will store your data in 2 dimensional numpy ndarray structures grouping them by dtypes. ndarray is basically a raw C array of data with a small header. So you can estimate it's size just by multiplying the size of the dtype it contains with the dimensions of the array.

For example: if you have 1000 rows with 2 np.int32 and 5 np.float64 columns, your DataFrame will have one 2x1000 np.int32 array and one 5x1000 np.float64 array which is:

4bytes*2*1000 + 8bytes*5*1000 = 48000 bytes


This I believe this gives the in-memory size any object in python. Internals need to be checked with regard to pandas and numpy

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

참고URL : https://stackoverflow.com/questions/18089667/how-to-estimate-how-much-memory-a-pandas-dataframe-will-need

반응형