Mam tego rodzaju dataframes

import pandas as pd

df1 = pd.DataFrame({'a':[1.1,1.1,1.1], 'b':[2.1,2.1,2.1], 'c':[3.1,3.1,3.1]})
df2 = pd.DataFrame({'aa':[1.2,1.2,1.2], 'bb':[2.2,2.2,2.2], 'cc':[3.2,3.2,3.2]})
df3 = pd.DataFrame({'aaa':[1.3,1.3,1.3], 'bbb':[2.3,2.3,2.3], 'ccc':[3.3,3.3,3.3]})

Te ramki zawsze mają ten sam kształt (i nazwy kolumn nie zawsze pasują do zamówienia alfabetycznego). Chcę znaleźć najlepszy sposób na połączenie ich kolumn w uzyskanej ramce, która wygląda jak:

     a   aa  aaa    b   bb  bbb    c   cc  ccc
0  1.1  1.2  1.3  2.1  2.2  2.3  3.1  3.2  3.3
1  1.1  1.2  1.3  2.1  2.2  2.3  3.1  3.2  3.3
2  1.1  1.2  1.3  2.1  2.2  2.3  3.1  3.2  3.3

Moje podejście jest zagnieżdżone pętle i wypełnienie kolumny nowej ramki w kolumnie:

df_new = pd.DataFrame()

for i in range(df1.shape[1]):
    for df in [df1, df2, df3]:
        df_new[df.columns[i]] = df.iloc[:, i]

print(df_new)

Działa, ale myślę, że jest bardziej niezawodny sposób.

Edytuj : Za pomocą pd.concat (dzięki @tbaki) można to zrobić również dwa kroki:

df_new = pd.concat([df1,df2,df3],axis=1)

small = df1.shape[1]
big = df_new.shape[1]

#create correct order
new_order = []

for i in range(small):
    new_order.extend(list(range(i, big, small)))

df_new.iloc[:, new_order]

Dzięki!

2
Alexey Trofimov 28 czerwiec 2017, 12:57

4 odpowiedzi

Najlepsza odpowiedź

IIUC:

In [17]: pd.concat([df1,df2,df3],axis=1) \
           .loc[:, np.concatenate([t for t in zip(df1.columns,df2.columns,df3.columns)])]
Out[17]:
     a   aa  aaa    b   bb  bbb    c   cc  ccc
0  1.1  1.2  1.3  2.1  2.2  2.3  3.1  3.2  3.3
1  1.1  1.2  1.3  2.1  2.2  2.3  3.1  3.2  3.3
2  1.1  1.2  1.3  2.1  2.2  2.3  3.1  3.2  3.3
3
MaxU 28 czerwiec 2017, 10:55

Utwórz nowy dataframe, dodając wszystkie kolumny z trzech danych danych w kolejności. To jest rozwiązanie.

import pandas as pd
df1 = pd.DataFrame({'a':[1.1,1.1,1.1], 'b':[2.1,2.1,2.1], 'c':[3.1,3.1,3.1]})
df2 = pd.DataFrame({'aa':[1.2,1.2,1.2], 'bb':[2.2,2.2,2.2], 'cc':[3.2,3.2,3.2]})
df3 = pd.DataFrame({'aaa':[1.3,1.3,1.3], 'bbb':[2.3,2.3,2.3], 'ccc':[3.3,3.3,3.3]})

df = pd.DataFrame()
for i,name in enumerate(df2.columns.values):
    df[df1.columns[i]]= df1[df1.columns[i]]
    df[name]= df2[name]
    df[df3.columns[i]]= df3[df3.columns[i]]
print(df)

Wynik:

     a   aa  aaa    b   bb  bbb    c   cc  ccc
0  1.1  1.2  1.3  2.1  2.2  2.3  3.1  3.2  3.3
1  1.1  1.2  1.3  2.1  2.2  2.3  3.1  3.2  3.3
2  1.1  1.2  1.3  2.1  2.2  2.3  3.1  3.2  3.3

To jest część, w której będziesz najbardziej zainteresowany!

for i,name in enumerate(df2.columns.values):
        df[df1.columns[i]]= df1[df1.columns[i]]
        df[name]= df2[name]
        df[df3.columns[i]]= df3[df3.columns[i]]

Więc co w zasadzie robię

df[df1.columns[i]]= df1[df1.columns[i]]

Tworzenie nowej dataframe z df[column_name] gdzie byłoby column_name df1.columns[i] - & gt; df1.columns[0] - & gt; a

Podobnie dla, df3.columns[i] - & gt; df3.columns[0] - & gt; aaa.

Jednak dostaję kolumnę name z drugiej dataframe df2 przy użyciu df2.columns.values. Więc w tym przypadku

df[name]= df1[name]

Wystarczy.

0
void 28 czerwiec 2017, 10:44

Możesz użyć Concat wtedy Reindex_axis:

df = pd.concat([df1,df2,df3],axis=1)
df.reindex_axis(sorted(df.columns), axis=1)

Wynik

     a   aa  aaa    b   bb  bbb    c   cc  ccc
0  1.1  1.2  1.3  2.1  2.2  2.3  3.1  3.2  3.3
1  1.1  1.2  1.3  2.1  2.2  2.3  3.1  3.2  3.3
2  1.1  1.2  1.3  2.1  2.2  2.3  3.1  3.2  3.3
1
Tbaki 28 czerwiec 2017, 10:08

Możesz użyć concat + < href = "http://pandas.pydata.org/pandas-docs/stable/generated/pandas.dataframe.sort_index.html" Rel = "NOFollow NefErr"> sort_index :

df = pd.concat([df1,df2,df3],axis=1).sort_index(axis=1)
print (df)
     a   aa  aaa    b   bb  bbb    c   cc  ccc
0  1.1  1.2  1.3  2.1  2.2  2.3  3.1  3.2  3.3
1  1.1  1.2  1.3  2.1  2.2  2.3  3.1  3.2  3.3
2  1.1  1.2  1.3  2.1  2.2  2.3  3.1  3.2  3.3

Trochę poprawił kolejną odpowiedź:

dfs= [df1,df2,df3]
cols = np.concatenate(list(zip(df1.columns,df2.columns,df3.columns)))
df = pd.concat(dfs,axis=1).reindex_axis(cols, axis=1)
print (df)
     a   aa  aaa    b   bb  bbb    c   cc  ccc
0  1.1  1.2  1.3  2.1  2.2  2.3  3.1  3.2  3.3
1  1.1  1.2  1.3  2.1  2.2  2.3  3.1  3.2  3.3
2  1.1  1.2  1.3  2.1  2.2  2.3  3.1  3.2  3.3

Lub:

from  itertools import chain

dfs= [df1,df2,df3]
cols = chain.from_iterable(list(zip(df1.columns,df2.columns,df3.columns)))
df = pd.concat(dfs,axis=1).reindex_axis(cols, axis=1)
print (df)
     a   aa  aaa    b   bb  bbb    c   cc  ccc
0  1.1  1.2  1.3  2.1  2.2  2.3  3.1  3.2  3.3
1  1.1  1.2  1.3  2.1  2.2  2.3  3.1  3.2  3.3
2  1.1  1.2  1.3  2.1  2.2  2.3  3.1  3.2  3.3
2
jezrael 28 czerwiec 2017, 11:06