如何合并两个数据框,同时排除NaN值列?

6

如果df1是:

       size_a  size_b
0       1       2
1       1       5
2       2       3
3       2       9
4       3       1
5       3       5
6       4       4

而 df2 是:

   size_a  size_b
0     1     2
1     2     NaN
2     3     NaN

I want the result as:

  size_a size_b
0       1       2
1       2       3
2       2       9
3       3       1
4       3       5

为了进行交集操作,我只想考虑df2中非NaN值-任何在df2中存在NaN的列值应该被忽略以执行交集。


如果你想排除NaN,那么结果应该只有一行,其中两个df的size_a=1且size_b=2。或者你的意图是将NaN视为通配符,并在df2中观察到NaN的任何值上与df1连接? - Scratch'N'Purr
我希望将NaN视为通配符,实际问题中有七列。 - Javed
3个回答

3

我认为你可以将它们合并两次,然后连接结果:

a. 普通的merge

part1 = pd.merge(df1, df2)
步骤二:合并含有 NaN 的行:
nans = df2[df2.size_b.isnull()]
part2 = pd.merge(df1, nans[["size_a"]], on="size_a")

c. concat 它们

pd.concat([part1, part2], ignore_index=True)

结果:
   size_a size_b
0       1      2
1       2      3
2       2      9
3       3      1
4       3      5

2

好的,对于这个问题,一种解决方案是首先按第一列进行合并,然后使用筛选功能消除不匹配的行。

df_out = df1.merge(df2, on='size_a',suffixes=('','_y'))

df_out.query('size_b_y == size_b or size_b_y != size_b_y').drop('size_b_y',axis=1)

输出:

   size_a  size_b
0       1       2
2       2       3
3       2       9
4       3       1
5       3       5

注意:size_by_y != size_b_y 是一种检查NaN值的巧妙技巧。

2

一种方法是首先按需要进行非通配符连接的列进行连接。这将有助于减少您在下游必须构建的条件过滤器。在上面的示例中,我看到size_a是其中之一:

new_df = df1.merge(df2, how='inner', on='size_a')

接下来,您需要应用过滤条件,其中任何其他列都有匹配项或者df2中这些列的值为NaN

new_df = new_df[(new_df['size_b_x'] == new_df['size_b_y']) | new_df['size_b_y'].isnull()]

最后,从df2中删除不必要的列(在列名中以_y为后缀表示)

new_df = new_df.drop('size_b_y', 1)

这个解决方案更易读和可扩展到多列。@Scratch'N'Purr 谢谢。 - Javed

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接