Zastanawiałem się ... Jeśli czytam, powiedzmy, plik csv o wielkości 400 MB w ramce danych pandy (używając read_csv lub read_table), czy istnieje sposób, aby oszacować, ile pamięci będzie to potrzebne? Próbuję tylko lepiej poznać ramki danych i pamięć ...
125
top
, a następnieShift + M
uporządkować moje zużycie pamięci.x=df.loc[[]]
zajmuje0.1
kilka sekund, aby zostać obliczony (aby wyodrębnić zero wierszy), a ponadto zajmuje setki megabajtów pamięci, tak jak oryginalna ramka danych, prawdopodobnie z powodu kopiowania pod spodem.Odpowiedzi:
df.memory_usage()
zwróci, ile zajmuje każda kolumna:Aby dołączyć indeksy, przekaż
index=True
.Aby uzyskać ogólne zużycie pamięci:
Ponadto przekazanie
deep=True
umożliwi dokładniejszy raport o wykorzystaniu pamięci, który uwzględnia pełne wykorzystanie zawartych obiektów.Dzieje się tak, ponieważ użycie pamięci nie obejmuje pamięci używanej przez elementy, które nie są składnikami tablicy if
deep=False
(przypadek domyślny).źródło
deep=True
deep=True
memory_usage()
zwraca użycie pamięci w bajtach (zgodnie z oczekiwaniami).Oto porównanie różnych metod -
sys.getsizeof(df)
jest najprostsze.W tym przykładzie
df
jest to ramka danych z 814 wierszami, 11 kolumnami (2 int, 9 obiektów) - odczytana z pliku kształtu o rozmiarze 427 kbsys.getsizeof (df)
df.memory_usage ()
df.info ()
Wyświetla informacje o ramce danych na standardowe wyjście. Z technicznego punktu widzenia są to kibibajty (KiB), a nie kilobajty - jak głosi dokument: „Wykorzystanie pamięci jest pokazane w czytelnych dla człowieka jednostkach (reprezentacja podstawowa-2)”. Zatem aby uzyskać bajty, należy pomnożyć przez 1024, np. 451,6 KiB = 462,438 bajtów.
źródło
g
odnosi się powyższy kod?df.info(memory_usage="deep")
, zwraca "392,6 MB", podczas gdysys.getsizeof(df)
idf.memory_usage(index=True, deep=True).sum()
zarówno zwrot w przybliżeniu "411718016" (~ 411MB). Czy możesz wyjaśnić, dlaczego te 3 wyniki nie są spójne? dziękidf.memory_usage(deep=True).sum()
zwraca prawie to samo zdf.memory_usage(index=True, deep=True).sum()
. w moim przypadkuindex
nie zajmuje dużo pamięci. Co ciekawe, znalazłem to411718016/1024/1024 = 392.6
, więc mogędf.info(memory_usage="deep")
użyć2^10
do konwersji bajtu na MB , co mnie dezorientuje. Mimo wszystko dzięki za pomoc: D.df.info
zwraca mebibajty (2 ^ 10), a nie megabajty (10 ^ 6) - poprawi odpowiedź.Pomyślałem, że przyniosę więcej danych do dyskusji.
Przeprowadziłem serię testów w tej sprawie.
Używając
resource
pakietu python , uzyskałem wykorzystanie pamięci przez mój proces.Zapisując csv w
StringIO
buforze, mogłem łatwo zmierzyć jego rozmiar w bajtach.Przeprowadziłem dwa eksperymenty, z których każdy utworzył 20 ramek danych o rosnących rozmiarach od 10 000 do 1 000 000 wierszy. Obie mają 10 kolumn.
W pierwszym eksperymencie użyłem tylko liczb zmiennoprzecinkowych w moim zbiorze danych.
W ten sposób pamięć wzrosła w porównaniu z plikiem csv jako funkcja liczby wierszy. (Rozmiar w megabajtach)
W drugim eksperymencie miałem takie samo podejście, ale dane w zbiorze danych składały się tylko z krótkich ciągów.
Wygląda na to, że zależność między wielkością csv a rozmiarem ramki danych może się znacznie różnić, ale rozmiar w pamięci zawsze będzie 2-3 razy większy (dla rozmiarów ramek w tym eksperymencie)
Chciałbym uzupełnić tę odpowiedź o więcej eksperymentów, proszę o komentarz, jeśli chcesz, żebym spróbował czegoś specjalnego.
źródło
Musisz to zrobić w odwrotnej kolejności.
Technicznie chodzi o pamięć (która obejmuje indeksy)
Więc 168 MB pamięci z plikiem 400 MB, 1 mln wierszy po 20 kolumn typu float
ZNACZNIE bardziej kompaktowy, gdy jest zapisywany jako binarny plik HDF5
Dane były losowe, więc kompresja nie pomaga zbytnio
źródło
read_csv
?iotop
liketop
/htop
do oglądania (w czasie rzeczywistym) wydajności IO.nbytes
będzie rażącym niedoszacowaniem, jeśli masz np. ciągi znaków w ramce danych.Jeśli znasz
dtype
s swojej tablicy, możesz bezpośrednio obliczyć liczbę bajtów potrzebnych do przechowywania danych + trochę dla samych obiektów Pythona. Przydatnym atrybutemnumpy
tablic jestnbytes
. Możesz uzyskać liczbę bajtów z tablic w pandachDataFrame
, wykonującobject
Tablice dtype przechowują 8 bajtów na obiekt (obiekt tablice dtype przechowują wskaźnik do nieprzezroczystegoPyObject
), więc jeśli masz ciągi w swoim csv, musisz wziąć pod uwagę, żeread_csv
przekształcą je wobject
tablice dtype i odpowiednio dostosujesz obliczenia.EDYTOWAĆ:
Zobacz
numpy
stronę typów skalarnych, aby uzyskać więcej informacji na tematobject
dtype
. Ponieważ przechowywane są tylko referencje, należy również wziąć pod uwagę rozmiar obiektu w tablicy. Jak mówi ta strona, tablice obiektów są nieco podobne dolist
obiektów Pythona .źródło
Tak jest. Pandy będą przechowywać twoje dane w dwuwymiarowych
ndarray
strukturach numpy , grupując je według typów.ndarray
jest w zasadzie surową tablicą danych w C z małym nagłówkiem. Możesz więc oszacować jego rozmiar, mnożąc rozmiar tego elementudtype
przez wymiary tablicy.Na przykład: jeśli masz 1000 wierszy z 2
np.int32
i 5np.float64
kolumnami, twoja DataFrame będzie miała jednąnp.int32
tablicę 2x1000 i jednąnp.float64
tablicę 5x1000, czyli:4 bajty * 2 * 1000 + 8 bajtów * 5 * 1000 = 48000 bajtów
źródło
DataFrame
?pandas
ma bardzo wydajną implementacjęread_table
w Cythonie (jest znacznie lepsza niż loadtxt numpy), więc zakładam, że analizuje i przechowuje dane bezpośrednio wndarray
.Myślę, że to daje rozmiar w pamięci dowolnego obiektu w Pythonie. Wewnętrzne należy sprawdzić pod kątem pand i drętwienia
źródło