2017-12-05 130 views
5

Próbuję połączyć dwie ramki danych w pandy, używając read_csv. Ale jedna z moich ramek danych (w tym przykładzie d1) jest zbyt duża, aby mój komputer mógł nią obsłużyć, więc używam argumentu iterator w read_csv.Scalanie ramek danych iteracyjnie z pandami

Powiedzmy mam dwie dataframes

d1 = pd.DataFrame({ 
    "col1":[1,2,3,4,5,6,7,8,9], 
    "col2": [5,4,3,2,5,43,2,5,6], 
    "col3": [10,10,10,10,10,4,10,10,10]}, 
    index=["paul", "peter", "lauren", "dave", "bill", "steve", "old-man", "bob", "tim"]) 

d2 = pd.DataFrame({ 
    "yes/no": [1,0,1,0,1,1,1,0,0]}, 
    index=["paul", "peter", "lauren", "dave", "bill", "steve", "old-man", "bob", "tim"]) 

muszę połączyć je tak, że każdy wiersz przechwytuje wszystkie dane dla każdej osoby, więc równowartość robi:

pd.concat((d1,d2), axis=1,join="outer") 

ale skoro mogę dopasowuję d1 do pamięci, używam read_csv (używam read_csv ponieważ już przetworzyłem ogromny plik i zapisałem go do formatu .csv, więc wyobraź sobie, że moja ramka danych d1 zawarta jest w pliku test.csv).

itera = pd.read_csv("test.csv",index_col="index",iterator=True,chunksize=2) 

Ale kiedy zrobić

for i in itera: 
    d2 = pd.concat((d2,i), axis=1,join="outer") 

moje wyjście jest pierwszym dataframe dołączone przez drugi dataframe.

moje wyjście wygląda następująco:

 col1 col2 col3 yes/no 
one  NaN NaN NaN  1.0 
two  NaN NaN NaN  0.0 
three NaN NaN NaN  1.0 
four NaN NaN NaN  0.0 
five NaN NaN NaN  1.0 
six  NaN NaN NaN  1.0 
seven NaN NaN NaN  1.0 
eight NaN NaN NaN  0.0 
nine NaN NaN NaN  0.0 
one  1.0 5.0 10.0  NaN 
two  2.0 4.0 10.0  NaN 
three 3.0 3.0 10.0  NaN 
four 4.0 2.0 10.0  NaN 
five 5.0 5.0 10.0  NaN 
six  6.0 43.0 4.0  NaN 
seven 7.0 2.0 10.0  NaN 
eight 8.0 5.0 10.0  NaN 
nine 9.0 6.0 10.0  NaN 

nadzieję, że moje pytanie ma sens :)

+1

Szybka odpowiedź: spróbuj użyć biblioteki dask, może obsługiwać duże dataframes który nie zmieści się w pamięci: http://dask.pydata.org/pl/latest/ – CrazyElf

+1

* moje wyjście jest pierwszą ramką danych dołączoną przez drugą ramkę danych * ... czego chcesz? – Parfait

+0

Wypróbuj zagnieżdżoną konkatencję: 'pd.concat ([d1, pd.concat (itera, ignore_index = True)])' – Parfait

Odpowiedz

1

myślę szukasz combine first metody. Zasadniczo aktualizuje on df1 wartościami z każdej porcji w iteratorze read_csv.

import pandas as pd 
from StringIO import StringIO 

d1 = pd.DataFrame({ 
    "col1":[1,2,3,4,5,6,7,8,9], 
    "col2": [5,4,3,2,5,43,2,5,6], 
    "col3": [10,10,10,10,10,4,10,10,10]}, 
    index=["paul", "peter", "lauren", "dave", "bill", "steve", "old-man", "bob", "tim"]) 


#d2 converted to string tho use with pd.read_csv 
d2 = StringIO("""y/n col5 
paul 1 
peter 0 
lauren 1 
dave 0 
bill 1 
steve 1 
old-man 1 
bob 0 
tim 0 
""") 

#For each chunk update d1 with data 
for chunk in pd.read_csv(d2, sep = ' ',iterator=True,chunksize=1): 
    d1 = d1.combine_first(chunk[['y/n']]) 
#Number formatting 
d1['y/n'] = d1['y/n'].astype(int) 

Które zwraca d1 patrząc jak:

  col1 col2 col3 y/n 
bill  5  5 10 1 
bob   8  5 10 0 
dave  4  2 10 0 
lauren  3  3 10 1 
old-man  7  2 10 1 
paul  1  5 10 1 
peter  2  4 10 0 
steve  6 43  4 1 
tim   9  6 10 0 
+0

Oznaczona jako odpowiedź, ponieważ daje mi wynik, o który prosiłem. Ale kiedy próbuję tego na ogromnym poziomie, to połączenie tych dwóch zbiorów danych sprawia, że ​​mój d2 staje się co najmniej o rząd wielkości większy (wygląda na to, że staje się dwa razy większy, bez wartości, które może znaleźć w kawałku, iteracja). Tak więc, mimo że nie jest to tym, czego chciałem, o to prosiłem; dzięki, myślę, że jestem teraz trochę bliżej mojego celu. –

+0

'd1' jest większy niż' d2'? Ostatnim razem, gdy czytałem twoje pytanie, pomyślałem coś przeciwnego. – dubbbdan

+0

Okej, właśnie wyjaśniłem post na przyszłość; ale tak jest. –