Pandas Merge - Bagaimana menghindari duplikasi kolom


93

Saya mencoba menggabungkan antara dua bingkai data. Setiap frame data memiliki dua level indeks (tanggal, cusip). Di kolom, beberapa kolom cocok antara keduanya (mata uang, tanggal penyerahan) misalnya.

Apa cara terbaik untuk menggabungkan ini dengan indeks, tetapi tidak mengambil dua salinan mata uang dan tanggal adj.

Setiap bingkai data terdiri dari 90 kolom, jadi saya mencoba untuk tidak menulis semuanya dengan tangan.

df:                 currency  adj_date   data_col1 ...
date        cusip
2012-01-01  XSDP      USD      2012-01-03   0.45
...

df2:                currency  adj_date   data_col2 ...
date        cusip
2012-01-01  XSDP      USD      2012-01-03   0.45
...

Bila saya lakukan:

dfNew = merge(df, df2, left_index=True, right_index=True, how='outer')

saya mendapat

dfNew:              currency_x  adj_date_x   data_col2 ... currency_y adj_date_y
date        cusip
2012-01-01  XSDP      USD      2012-01-03   0.45             USD         2012-01-03

Terima kasih! ...

Jawaban:


143

Anda dapat mengerjakan kolom yang hanya ada di satu DataFrame dan menggunakan ini untuk memilih subset kolom dalam gabungan.

cols_to_use = df2.columns.difference(df.columns)

Kemudian lakukan penggabungan (perhatikan bahwa ini adalah objek indeks tetapi memiliki tolist()metode praktis ).

dfNew = merge(df, df2[cols_to_use], left_index=True, right_index=True, how='outer')

Ini akan menghindari setiap kolom bentrok dalam penggabungan.


Bagaimana jika kuncinya adalah kolom dan disebut sama? Itu akan dijatuhkan dengan langkah pertama.
Guerra

Terima kasih banyak!!!
Cloudy_Green

88

Saya menggunakan suffixesopsi dalam .merge():

dfNew = df.merge(df2, left_index=True, right_index=True,
                 how='outer', suffixes=('', '_y'))
dfNew.drop(dfNew.filter(regex='_y$').columns.tolist(),axis=1, inplace=True)

Terima kasih @ijoseph


15
Akan menjadi jawaban yang lebih membantu jika menyertakan kode untuk filtering (yang cukup mudah, namun masih memakan waktu untuk mencari / rawan kesalahan untuk mengingat). yaitu dfNew.drop(list(dfNew.filter(regex='_y$')), axis=1, inplace=True)
ijoseph

5

Saya baru mengenal Pandas tetapi saya ingin mencapai hal yang sama, secara otomatis menghindari nama kolom dengan _x atau _y dan menghapus data duplikat. Aku akhirnya melakukannya dengan menggunakan ini jawaban dan ini salah satu dari Stackoverflow

sales.csv

    kota; negara bagian; unit
    Mendocino; CA; 1
    Denver; CO; 4
    Austin; TX; 2

revenue.csv

    branch_id; city; pendapatan; state_id
    10; Austin; 100; TX
    20; Austin; 83; TX
    30; Austin; 4; TX
    47; Austin; 200; TX
    20; Denver; 83; CO
    30; Springfield; 4; Saya

merge.py import pandas

def drop_y(df):
    # list comprehension of the cols that end with '_y'
    to_drop = [x for x in df if x.endswith('_y')]
    df.drop(to_drop, axis=1, inplace=True)


sales = pandas.read_csv('data/sales.csv', delimiter=';')
revenue = pandas.read_csv('data/revenue.csv', delimiter=';')

result = pandas.merge(sales, revenue,  how='inner', left_on=['state'], right_on=['state_id'], suffixes=('', '_y'))
drop_y(result)
result.to_csv('results/output.csv', index=True, index_label='id', sep=';')

Saat menjalankan perintah merge, saya mengganti _xsufiks dengan string kosong dan saya dapat menghapus kolom yang diakhiri dengan_y

output.csv

    id; kota; negara bagian; unit; branch_id; pendapatan; state_id
    0; Denver; CO; 4; 20; 83; CO
    1; Austin; TX; 2; 10; 100; TX
    2; Austin; TX; 2; 20; 83; TX
    3; Austin; TX; 2; 30; 4; TX
    4; Austin; TX; 2; 47; 200; TX

4

Berdasarkan jawaban @ rprog, Anda dapat menggabungkan berbagai langkah sufiks & filter ke dalam satu baris menggunakan regex negatif:

dfNew = df.merge(df2, left_index=True, right_index=True,
             how='outer', suffixes=('', '_DROP')).filter(regex='^(?!.*_DROP)')

Atau menggunakan df.join:

dfNew = df.join(df2),lsuffix="DROP").filter(regex="^(?!.*DROP)")

Regex di sini menyimpan apa pun yang tidak diakhiri dengan kata "DROP", jadi pastikan untuk menggunakan sufiks yang belum muncul di antara kolom.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.