menggabungkan dua dataframe dan menambahkan level kolom dengan nama

9

Hai, saya telah menggali concat, bergabung, dan menggabungkan metode untuk panda dan sepertinya tidak dapat menemukan apa yang saya inginkan.

Mari kita asumsikan saya memiliki dua dataframe

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

Sekarang saya ingin membuat kerangka data baru dengan kolom digabungkan, saya pikir itu paling mudah untuk menjelaskan jika saya membuat indeks multi untuk bagaimana saya ingin kolom

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]])

Sekarang jika saya membuat kerangka data kosong dengan indeks multi ini untuk kolom

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     -  -     -  -     -  -

Pertanyaan saya adalah, apa yang menggabungkan, menyatukan, atau bergabung yang saya gunakan untuk mendapatkan itu? Saya sudah mencoba banyak hal untuk konser ... dalam, luar, dll. Tampaknya saya tidak dapat menemukan apa yang saya inginkan. Satu-satunya hal yang dapat saya pikirkan adalah membuat dataframe yang kosong dan kemudian mengisi kembali.

Sunting: Setelah mencoba tanggapan Jezrael, itu dekat tetapi tidak persis. Yang saya inginkan seperti kolom bersarang semacam? Sebagai contoh

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

Atau

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

Jadi ini adalah solusi yang saya buat tetapi dari iterasi di kolom.

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
sumber

Jawaban:

8

Saya pikir Anda perlu concatdengan keysparameter dan axis=1, perubahan urutan tingkat terakhir dengan DataFrame.swapleveldan mengurutkan berdasarkan tingkat pertama dengan 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

Untuk bekerja dengan MultiIndexdimungkinkan, gunakan 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

Jika ingin pilih MultiIndex columngunakan tuple:

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

Jika ingin pilih berdasarkan indeks dan penggunaan kolom loc:

print (df1.loc[4, ('Col 1', 'A')])
A
jezrael
sumber
2
Itu berhasil! Terima kasih banyak!
Melendowski