问题描述
@H_404_0@我正在尝试使用pandas复制sql连接,但是在连接键中使用Null值时遇到了麻烦。
例如数据框:
df_1 = pd.DataFrame({'K1':[1,2,3,2],'K2':['a','b','c',np.nan],'K3':'x y z y'.split()})
df_2 = pd.DataFrame({'Z1':[1,3],'Z2':['a',np.nan,'c'],'Z3':'x y y z'.split(),'I':[10,40,50,20]})
@H_404_0@可以使用以下方式加入:
df_join = pd.merge(df_1,df_2,left_on=['K1','K2','K3'],right_on=['Z1','Z2','Z3'],how='inner')
@H_404_0@输出:
@H_404_0@ RSA should I use X.509 or PKCS #1
@H_404_0@我认为这在技术上是正确的,因为K2和Z2中都存在空值,但是在sql中,这些空值不被识别为匹配项。因此,对于K1 = 2,列“ I”应为NaN。
@H_404_0@就我而言,我使用列“ I”的值进行另一次计算,因此,为解决这一问题,我添加了:
df_join.loc[df_join['K2'].isna(),'I'] = np.nan
df_join.drop_duplicates()
@H_404_0@但是感觉不对。有没有一种方法可以直接在合并操作中或更清晰地复制sql行为?
解决方法
如果您不希望NaN出现在合并结果中,则可以先将其删除(.dropna())在每个df上:
df_join = pd.merge(df_1.dropna(),df_2.dropna(),left_on=['K1','K2','K3'],right_on=['Z1','Z2','Z3'],how='inner')
K1 K2 K3 Z1 Z2 Z3 I
0 1 a x 1 a x 10
1 3 c z 3 c z 20
,
如果您告诉数据框在具有NaN的键上进行合并,则他会假设您要在两个键均为NaN的键上进行合并,并且在这种情况下仅使用1或2个键。
解决方案是,如果您不想合并在那些列上具有NaN的任何内容,请首先在您的键列上应用dropna()方法。
所以:
df_join = pd.merge(df_1.dropna(subset=['K1','K3']),df_2.dropna(subset=['Z1','Z3']),how='inner')