У меня есть ниже Dataframes
import pandas as pd
dat1 = pd.DataFrame({'col1' : ['AA', 'AA'], 'col2' : [10,20]})
dat2 = pd.DataFrame({'col1' : ['AA', 'BB', 'AA', 'BB'], 'col2' : [11,11,11,11]})
Теперь я хочу присоединиться к левому соединению выше 2 на основе col1
и col2
, где dat1.col2 < dat2.col2
Я попробовал ниже:
dat_com = pd.merge(dat1, dat2, how = 'left', on = 'col1')
dat_com[dat_com['col2_x'] < dat_com['col2_y']]
Но я думаю, что это неправильный подход, поскольку он исключает второй ряд dat1
, который, по моему мнению, должен быть в финале dat_com
, поскольку я присоединяюсь слева.
Не могли бы вы помочь исправить вышеуказанный метод?
Потому что это левое соединение. Поэтому должна быть последняя строка с dat_com .col2_x = 20 and dat_com .col2_y = NaN
Эта строка была бы там, если бы не было совпадений. Но в правой части есть совпадения, поэтому строка NaN не добавляется. Кроме того, у вас есть второе условие, которое действует после выполнения соединения.
Другими словами, если вы намеревались выполнить левое соединение, а затем применить к нему фильтр, ваш код сделает это правильно. Так может быть, вы на самом деле хотели заняться чем-то другим?
Я хочу применить эти два условия одновременно, как это делает SQL
.
Я понимаю. Слияние в pandas недостаточно мощное для этого, оно может объединяться только при совпадениях. Но люди написали собственные пакеты. Дополнительную информацию см. здесь: stackoverflow.com/questions/77146492/pandas-merge-on-inequality
Код
dat_com['col2_y'] = dat_com['col2_y'].where(dat_com['col2_x'] < dat_com['col2_y'])
cond1 = dat_com['col2_y'].isna()
cond2 = cond1.groupby(dat_com['index']).transform(all)
cond3 = ~cond2 & ~cond1
cond4 = cond2 & ~dat_com['index'].duplicated()
out = dat_com[cond3 | cond4]
вне:
index col1 col2_x col2_y
0 0 AA 10 11.0
1 0 AA 10 11.0
2 1 AA 20 NaN
Если вам не нужен index column
, удалите его.
проверьте на другом примере
import pandas as pd
dat1 = pd.DataFrame({'col1' : ['AA', 'AA'], 'col2' : [10,20]})
dat2 = pd.DataFrame({'col1' : ['AA', 'AA', 'BB', 'AA', 'BB'], 'col2' : [8, 11, 12, 13, 14]})
дата1:
col1 col2
0 AA 10
1 AA 20
дата2:
col1 col2
0 AA 8
1 AA 11
2 BB 12
3 AA 13
4 BB 14
вне:
index col1 col2_x col2_y
1 0 AA 10 11.0
2 0 AA 10 13.0
3 1 AA 20 NaN
Как вы думаете, почему он должен включать второй ряд? Второе условие о том, что
col2_x
меньшеcol2_y
, исключает эту строку из окончательного результата.