Połącz razem listę ramek danych pand

129

Mam listę ramek danych Pandas, które chciałbym połączyć w jedną ramkę danych Pandas. Używam Pythona 2.7.10 i Pandas 0.16.2

Utworzyłem listę ramek danych z:

import pandas as pd
dfs = []
sqlall = "select * from mytable"

for chunk in pd.read_sql_query(sqlall , cnxn, chunksize=10000):
    dfs.append(chunk)

Zwraca listę ramek danych

type(dfs[0])
Out[6]: pandas.core.frame.DataFrame

type(dfs)
Out[7]: list

len(dfs)
Out[8]: 408

Oto kilka przykładowych danych

# sample dataframes
d1 = pd.DataFrame({'one' : [1., 2., 3., 4.], 'two' : [4., 3., 2., 1.]})
d2 = pd.DataFrame({'one' : [5., 6., 7., 8.], 'two' : [9., 10., 11., 12.]})
d3 = pd.DataFrame({'one' : [15., 16., 17., 18.], 'two' : [19., 10., 11., 12.]})

# list of dataframes
mydfs = [d1, d2, d3]

Chciałbym połączyć d1, d2i d3do jednej pandy dataframe. Alternatywnie, chunksizebardzo pomocna byłaby metoda wczytywania dużej tabeli bezpośrednio do ramki danych podczas korzystania z tej opcji.

Biała broda
źródło

Odpowiedzi:

245

Biorąc pod uwagę, że wszystkie ramki danych mają te same kolumny, możesz po prostu concatje:

import pandas as pd
df = pd.concat(list_of_dataframes)
Głęboka przestrzeń
źródło
1
jeśli nie mają tych samych kolumn, możesz najpierw przesłać je na dyktę, a następnie użyć from_dict - patrz poniżej
meyerson
1
jeśli chcesz dodać kolumny, pamiętaj o dodaniu argumentu axis = 1
ford prefect
3
Myślę, że nawet jeśli niektóre data.framenie mają tych samych kolumn to NaNzostaną wstawione bez wyrzucania błędu w nowej wersjipandas
joel.wilson
7

Jeśli ramki danych NIE mają wszystkich tych samych kolumn, spróbuj wykonać następujące czynności:

df = pd.DataFrame.from_dict(map(dict,df_list))
meyerson
źródło
7
To rozwiązanie nie działa dla mnie na Pythonie 3.6.5 / Pandas v0.23.0. To błędy z TypeError: data argument can't be an iterator. Konwersja do listfirst (naśladująca Python 2.7) również daje nieoczekiwane rezultaty.
jpp
a jeśli wszystkie ramki danych mają tę samą kolumnę, jak powinniśmy zrobić?
Thony Nadhir
6

Możesz to również zrobić za pomocą programowania funkcjonalnego:

from functools import reduce
reduce(lambda df1, df2: df1.merge(df2, "outer"), mydfs)
Jay Wong
źródło
2
from functools import reducedo użyciareduce
nishant
Nie polecałbym wykonywania scalania parami dla wielu ramek DataFrame, nie jest to wcale wydajne. Zobacz pd.concatlub join, obie domyślnie akceptują listę ramek i dołączają do indeksu.
cs95
0

concat działa również dobrze z listą złożoną pobraną za pomocą polecenia „loc” w odniesieniu do istniejącej ramki danych

df = pd.read_csv('./data.csv') # ie; Dataframe pulled from csv file with a "userID" column

review_ids = ['1','2','3'] # ie; ID values to grab from DataFrame

# Gets rows in df where IDs match in the userID column and combines them 

dfa = pd.concat([df.loc[df['userID'] == x] for x in review_ids])
Lelouch
źródło