Menggabungkan 2 panda DataFrames dengan kondisi tertentu

Saya tidak tahu cara menggabungkan 2 panda DataFrames dengan kondisi tertentu.

Aku punya ini:

import pandas as pd

df1 = pd.DataFrame({'Name': ['A', 'A', 'A', 'B' ,'B' ,'B'],
                    'Date': ['10/15/2019', '10/16/2019', '10/17/2019', '10/15/2019', '10/16/2019', '10/17/2019'], 
                    'Value 1': [101, 102, 103, 201, 202, 203],
                    'Value 2': ['A1', 'A2', 'A3', 'B1', 'B2', 'B3']})

df2 = pd.DataFrame({'Name': ['A', 'A', 'B', 'B' ,'C'],
                    'Date': ['10/14/2019', '10/15/2019', '10/13/2019', '10/18/2019', '10/18/2019'], 
                    'Value 3': [2, 2, 22, 44, 222]})

Saya harus melakukan ini

Saya hanya perlu menggabungkan nama yang ada di df1, tetapi menambahkan tanggal yang ada di df2. Namun, tanggal tersebut harus lebih besar dari 13/10/2019.

Yang paling dekat yang bisa saya dapatkan adalah

df_m = pd.merge(df1, df2, how='outer', left_on=['Name', 'Date'], right_on=['Name', 'Date'], sort=True)

Tapi ini mencakup semuanya ('C' dari df2 - saya tidak membutuhkannya dan tanggal 13/10/2019 untuk 'B' - saya juga tidak membutuhkannya).

Saya sangat menghargai bantuan apa pun.

Diedit: Kita dapat menghilangkan kondisi tanggal yang lebih besar dari 13/10/2019 - Saya menemukan jawabannya dengan membuat df2_mod lain di mana saya tidak memasukkan tanggal yang tidak saya perlukan. Namun, beberapa tanggal yang ada di df2_mod tidak ada di df1 dan saya perlu menggabungkannya dengan nilai 3. Namun saya tidak memerlukan Nama dari df2 ke df1 yang tidak ada di df1


person user_unknown    schedule 24.12.2019    source sumber
comment
Persyaratan Anda tidak jelas. Jika Anda mengambil semuanya dari df1 dan df2, itu adalah gabungan luar. Gabungan luar akan selalu menyertakan hasil 'C' karena mencakup semuanya dari kedua kerangka data. Kemudian jika Anda melakukan subset untuk tanggal › 13/10/2019, hasil C akan tetap karena tanggal untuk record tersebut adalah 18/10. Entah Anda menjelaskan sesuatu yang tidak mungkin, atau Anda perlu menyatakan kembali kebutuhan Anda dengan lebih jelas.   -  person Julian Drago    schedule 24.12.2019
comment
Jadi, saya perlu memenuhi 2 syarat: 1. Gabungkan bagian luar tetapi jangan sertakan nama yang tidak ada di df1 2. Gabungkan semua tanggal dari df2, meskipun tidak ada di df1.   -  person user_unknown    schedule 24.12.2019
comment
Saya memperbarui pertanyaan awal saya. Terima kasih.   -  person user_unknown    schedule 24.12.2019


Jawaban (1)


Berikut ini salah satu solusinya (saya tidak memfilter tanggal yang lebih besar dari 13/10/2019, seperti yang dinyatakan dalam pertanyaan yang diperbarui):

  1. Pertama kita memfilter df2 dan membuang semua 'Names' yang tidak ada di df1
  2. Lakukan inner join dengan df1 dan df2_filtered pada kolom Nama dan Tanggal
  3. Urutkan nilai dan buat ulang indeks

import pandas as pd

df1 = pd.DataFrame({'Name': ['A', 'A', 'A', 'B' ,'B' ,'B'],
                    'Date': ['10/15/2019', '10/16/2019', '10/17/2019', '10/15/2019', '10/16/2019', '10/17/2019'],
                    'Value 1': [101, 102, 103, 201, 202, 203],
                    'Value 2': ['A1', 'A2', 'A3', 'B1', 'B2', 'B3']})

df2 = pd.DataFrame({'Name': ['A', 'A', 'B', 'B' ,'C'],
                    'Date': ['10/14/2019', '10/15/2019', '10/13/2019', '10/18/2019', '10/18/2019'],
                    'Value 3': [2, 2, 22, 44, 222]})

df2_filtered = df2[df2['Name'].isin(df1['Name'])]       # we want df2 rows with `Names` that exists in df1
print(df1.merge(df2_filtered, on=['Name', 'Date'], how='outer').sort_values(['Name', 'Date']).reset_index(drop=True))

Cetakan:

  Name        Date  Value 1 Value 2  Value 3
0    A  10/14/2019      NaN     NaN      2.0
1    A  10/15/2019    101.0      A1      2.0
2    A  10/16/2019    102.0      A2      NaN
3    A  10/17/2019    103.0      A3      NaN
4    B  10/13/2019      NaN     NaN     22.0
5    B  10/15/2019    201.0      B1      NaN
6    B  10/16/2019    202.0      B2      NaN
7    B  10/17/2019    203.0      B3      NaN
8    B  10/18/2019      NaN     NaN     44.0
person Andrej Kesely    schedule 24.12.2019
comment
Terima kasih banyak, ini masuk akal! Saya memberi suara positif pada jawabannya! Ini sangat membantu saya! - person user_unknown; 25.12.2019