2017-10-31 104 views
5

Załaduję ogromny csv (18 GB) do pamięci i zauważam bardzo duże różnice między R i Pythonem. To jest na AWS ec2 r4.8xlarge which has 244 Gb of memory. Oczywiście jest to skrajny przykład, ale zasada obowiązuje również w przypadku mniejszych plików na prawdziwych maszynach.Ładowanie bardzo dużego zestawu danych CSV do Pythona i R, walki Pandy

Podczas korzystania z pd.read_csv mój plik trwał około 30 minut i zajmował 174 GB pamięci. Zasadniczo tak bardzo, że nie mogę z tym nic zrobić. W przeciwieństwie do R fread() z pakietu data.table zajęło ~ 7 minut i tylko ~ 55 GB pamięci.

Dlaczego obiekt pandy zajmuje o wiele więcej pamięci niż obiekt data.table? Ponadto, dlaczego zasadniczo obiekt pandy jest prawie 10 razy większy niż plik tekstowy na dysku? To nie jest tak, że .csv to szczególnie skuteczny sposób przechowywania danych w pierwszej kolejności.

+0

Podobny do [https://stackoverflow.com/questions/17444679/reading-a-huge-csv-file](https://stackoverflow.com/questions/17444679/reading-a-huge-csv-file) – RobertMc

+1

@RobertMc nie pod względem pand – roganjosh

+0

Czy używasz 1.10.5 z 'fread', który jest nowy, w dev, a jeszcze nie na CRAN? Spróbuj również [paratext] (https://github.com/wiseio/paratext). –

Odpowiedz

9

Nie będziesz w stanie pokonać prędkości fread, ale jeśli chodzi o użycie pamięci, domyślam się, że masz liczby całkowite, które są odczytywane jako 64-bitowe liczby całkowite w pythonie.

Zakładając, że plik wygląda tak:

a,b 
123456789,12345 

W R, dostaniesz:

sapply(fread('test.txt'), class) 
#   a   b 
#"integer64" "integer" 

Natomiast w Pythonie (na komputerze 64-bitowym):

pandas.read_csv('test.txt').dtypes 
#a int64 
#b int64 

W ten sposób zużyjesz więcej pamięci w pythonie. Można wymusić typ w read_csv jako obejście:

pandas.read_csv('test.txt', dtype={'b': numpy.int32}).dtypes 
#a int64 
#b int32 

Małe całkowitymi są również będzie powodem dla obu obiektów R i Python biorących więcej miejsca niż plik .csv, ponieważ na przykład "1" w pliku .csv zajmuje 2 bajty (char + przecinek lub koniec linii), ale 4 lub 8 bajtów w pamięci.

+0

Myślę, że to jest prawdopodobnie na miejscu. Nigdy nie myślałem, aby użyć opcji 'dtype' w read_csv. Ponadto, wiele kolumn jest po prostu binarnych, ale założę się, że traktuje wszystkie te 1 i 0 także jako liczby całkowite. Czy istnieje skuteczny typ numpy dla liczb całkowitych binarnych (lub bardzo małych), czy też powinienem użyć 'int32'? Prawdopodobnie nie wpłynie to na prędkość, ale zdecydowanie powinno sprawić, że będzie znacznie mniejsza. Dzięki. – seth127

+0

Możesz spróbować użyć 'int8'. – eddi

+0

Spróbuję tego. Każdy pomysł, czy istnieje sposób, aby powiedzieć "ta kolumna jest int64, wszystkie inne są int8"? Dokumentacja mówi, że musisz to zrobić jako dyktando, ale mam kilka tysięcy kolumn (stąd duży rozmiar pliku), więc wydaje się nieco nudny. – seth127

-1

Możesz spróbować użyć pakietu dask. Zasadniczo daszka zapewnia implementację DataFrame pandy, ale może używać obliczeń równoległych i rozproszonych oraz obliczeń opóźnionych.