Saya memiliki dua Dataframe (a hashable, b unhashable)

   Foo              
    a   b           
A   1   2       
B   1   3       
C   0   4       

 Bar
a   b
A   1   2
D   0   6

Jika indeks atau kode (A,B,C,D dalam hal ini) sama, maka a dan b harus sama. Saya ingin tahu bagaimana menggabungkan dua kerangka data ini yang menunjukkan di mana kolom itu berada seperti ini.

    a   b   Foo   Bar
A   1   2    1     1
B   1   3    1     0
C   0   4    1     0
D   0   6    0     1

Apa cara paling efisien untuk mendapatkan kerangka data ini?

1
niukasu 31 Agustus 2017, 09:14

2 jawaban

Jawaban Terbaik

Solusi satu baris jika tidak ada NaN dalam data dengan assign dan luar bergabung dengan merge. Tapi perlu tambahkan reset_index untuk kolom dari index, karena perlu menggabungkan kolom dengan indeks bersama. set_index terakhir dengan < a href="http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.rename_axis.html" rel="nofollow noreferrer">rename_axis untuk membuat index kembali.

Parameter on dapat dihapus, karena tergabung pada kolom yang sama di kedua DataFrames.

df = pd.merge(Foo.reset_index().assign(Foo=1), 
              Bar.reset_index().assign(Bar=1), how='outer') \
       .fillna(0) \
       .set_index('index') \
       .rename_axis(None) \
       .astype(int)
print (df)
   a  b  Foo  Bar
A  1  2    1    1
B  1  3    1    0
C  0  4    1    0
D  0  6    0    1

Jika memungkinkan NaN maka gunakan subset hanya untuk kolom indikator:

df = pd.merge(Foo.reset_index().assign(Foo=1), 
              Bar.reset_index().assign(Bar=1), how='outer') \
       .set_index('index') \
       .rename_axis(None) 
df[['Foo','Bar']] = df[['Foo','Bar']].fillna(0).astype(int)
print (df)
   a    b  Foo  Bar
A  1  NaN    1    1
B  1  3.0    1    0
C  0  4.0    1    0
D  0  6.0    0    1

pandas telah menerapkan cara serupa dengan parameter indicator:

df = pd.merge(Foo.reset_index().assign(Foo=1), 
              Bar.reset_index().assign(Bar=1), how='outer', indicator='indicator') \
       .set_index('index') \
       .rename_axis(None) 
print (df)
   a  b  Foo  Bar   indicator
A  1  2  1.0  1.0        both
B  1  3  1.0  NaN   left_only
C  0  4  1.0  NaN   left_only
D  0  6  NaN  1.0  right_only
1
jezrael 31 Agustus 2017, 07:05

Anda harus dapat melakukan ini menggunakan df.merge:

df1['Foo'] = 1
df2['Bar'] = 1
out = df1.merge(df2, on=['a', 'b'], how='outer').fillna(0).astype(int)

print(out)
   a  b  Foo  Bar
0  1  2    1    1
1  1  3    1    0
2  0  4    1    0
3  0  6    0    1
2
cs95 31 Agustus 2017, 06:27