Führen Sie zwei Datenrahmen zusammen und fügen Sie Spaltenebene mit Namen hinzu

9

Hallo, ich habe die Concat-, Join- und Merge-Methoden für Pandas durchgearbeitet und kann anscheinend nicht finden, was ich will.

Nehmen wir an, ich habe zwei Datenrahmen

A = pd.DataFrame("A",index=[0,1,2,3,4],columns=['Col 1','Col 2','Col 3'])
B = pd.DataFrame("B",index=[0,1,2,3,4],columns=['Col 1','Col 2','Col 3'])
>>> A
  Col 1 Col 2 Col 3
0     A     A     A
1     A     A     A
2     A     A     A
3     A     A     A
4     A     A     A
>>> B
  Col 1 Col 2 Col 3
0     B     B     B
1     B     B     B
2     B     B     B
3     B     B     B
4     B     B     B

Jetzt möchte ich einen neuen Datenrahmen mit den zusammengeführten Spalten erstellen. Ich denke, es ist am einfachsten zu erklären, ob ich einen Multi-Index für die gewünschten Spalten erstelle

index = pd.MultiIndex.from_product([A.columns.values,['A','B']])
>>> index
MultiIndex(levels=[['Col 1', 'Col 2', 'Col 3'], ['A', 'B']],
           labels=[[0, 0, 1, 1, 2, 2], [0, 1, 0, 1, 0, 1]])

Nun, wenn ich einen leeren Datenrahmen mit diesem Multi-Index für die Spalten mache

empty_df = pd.DataFrame('-',index=A.index,columns=index)
>>> empty_df
  Col 1    Col 2    Col 3
      A  B     A  B     A  B
0     -  -     -  -     -  -
1     -  -     -  -     -  -
2     -  -     -  -     -  -
3     -  -     -  -     -  -
4     -  -     -  -     -  -

Meine Frage ist, welche Zusammenführung, Concat oder Join verwende ich, um das zu erhalten? Ich habe mehrere Dinge für concat ausprobiert ... innen, außen usw. Ich kann nicht finden, was ich will. Ich kann mir nur vorstellen, den leeren Datenrahmen zu erstellen und dann wieder zu füllen.

Bearbeiten: Nachdem Sie Jezraels Antwort ausprobiert haben, ist es nah, aber nicht genau. Was ich will, ist wie verschachtelte Spalten? Zum Beispiel

empty_df['Col 1']
>>> empty_df['Col 1']
   A  B
0  -  -
1  -  -
2  -  -
3  -  -
4  -  -

Oder

>>> empty_df['Col 1']['A']
0    -
1    -
2    -
3    -
4    -
Name: A, dtype: object

Das ist also eine Lösung, die ich mir ausgedacht habe, die aber durch das Durchlaufen der Spalten entstanden ist.

row_idx = A.index.union(B.index)
col_idx = pd.MultiIndex.from_product([A.columns.values,['A','B']])
new_df = pd.DataFrame('-',index=row_idx,columns=col_idx)
for column in A.columns:
   new_df.loc[:,(column,'A')] = A[column]
   new_df.loc[:,(column,'B')] = B[column]
>>> new_df
  Col 1    Col 2    Col 3
      A  B     A  B     A  B
0     A  B     A  B     A  B
1     A  B     A  B     A  B
2     A  B     A  B     A  B
3     A  B     A  B     A  B
4     A  B     A  B     A  B
>>> new_df['Col 1']
   A  B
0  A  B
1  A  B
2  A  B
3  A  B
4  A  B
>>> new_df['Col 1']['A']
0    A
1    A
2    A
3    A
4    A
Name: A, dtype: object
Melendowski
quelle

Antworten:

8

Ich denke, Sie müssen concatmit keysParameter und axis=1, letzte Änderung der Reihenfolge der Ebenen nach DataFrame.swaplevelund Sortieren nach der ersten Ebene nach DataFrame.sort_index:

df1 = (pd.concat([A, B], axis=1, keys=('A','B'))
         .swaplevel(0,1, axis=1)
         .sort_index(axis=1, level=0))
print (df1)
  Col 1    Col 2    Col 3   
      A  B     A  B     A  B
0     A  B     A  B     A  B
1     A  B     A  B     A  B
2     A  B     A  B     A  B
3     A  B     A  B     A  B
4     A  B     A  B     A  B

Zum Arbeiten mit MultiIndexist möglich DataFrame.xs:

print (df1.xs('Col 1', axis=1, level=0))
   A  B
0  A  B
1  A  B
2  A  B
3  A  B
4  A  B

Wenn Sie möchten, wählen Sie MultiIndex columnverwenden tuple:

print (df1[('Col 1', 'A')])
0    A
1    A
2    A
3    A
4    A
Name: (Col 1, A), dtype: object

Wenn Sie nach Index und Spalte auswählen möchten, verwenden Sie loc:

print (df1.loc[4, ('Col 1', 'A')])
A
jezrael
quelle
2
Das hat es geschafft! Vielen Dank!
Melendowski