我想与 pandas 执行 NVL 连接,例如在 SQL 中:
select * from TA
join TB on
TA.column = NVL(TB.column, TA.column)
这是一个完整的 SQL 示例,显示了预期的结果:
/* first table a, with a single column "aa" :
aa
1
2
2 */
create table a as
select 1 aa from dual
union all
select 2 aa from dual
union all
select 2 aa from dual;
/* second table b, with a single column as well:
aa
1
null
null
4 */
create table b as
select 1 aa from dual
union all
select null aa from dual
union all
select null aa from dual
union all
select 4 aa from dual;
遵循 nvl 连接,例如:
select a.aa from a join b on a.aa = nvl(b.aa, a.aa);
结果是这样的:
1
1
1
2
2
2
2
也就是说,表
a
中的每一行出现的次数与它在b
中存在或为空的次数一样多。
如您所见,两个表的行数不一定相同。
我尝试使用类似 combine_first 的东西,但它不起作用。
如果可能的话,在 pandas 中执行此操作最简单有效的方法是什么?
如果有多个 NVL 条件怎么办?
谢谢
IIUC,您可以在 NaN 行上组合经典
merge
和交叉 merge
:
# merge df1/df2 on "aa"
# cross-merge the NA rows
out = (pd.concat([df1.merge(df2, on='aa'),
df1.merge(df2[df2['aa'].isna()].drop(columns='aa'),
how='cross')], ignore_index=True)
.sort_values(by='aa', ignore_index=True) # optional
)
变体,直接复制
df1
拥有 NaN 的次数(如果只有几个 NaN,可能就足够高效了)。
# count the number of NAs in df2['aa']
n_na = df2['aa'].isna().sum()
# merge df1/df2 on "aa"
# and copy as many rows as there are NAs
out = (pd.concat([df1.merge(df2, on='aa')]+[df1]*n_na,
ignore_index=True)
.sort_values(by='aa', ignore_index=True) # optional
)
输出:
aa
0 1
1 1
2 1
3 2
4 2
5 2
6 2