如何在熊猫中合并两个数据框以替换 nan

Posted

技术标签:

【中文标题】如何在熊猫中合并两个数据框以替换 nan【英文标题】:How to merge two dataframe in pandas to replace nan 【发布时间】:2014-09-25 14:04:20 【问题描述】:

我想在 pandas 中这样做:

我有 2 个数据框,A 和 B,我只想用 B 值替换 A 的 NaN。

A                                                
2014-04-17 12:59:00  146.06250  146.0625  145.93750  145.93750
2014-04-17 13:00:00  145.90625  145.9375  145.87500  145.90625
2014-04-17 13:01:00  145.90625       NaN  145.90625        NaN
2014-04-17 13:02:00        NaN       NaN  145.93750  145.96875

B
2014-04-17 12:59:00   146 2/32   146 2/32  145 30/32  145 30/32
2014-04-17 13:00:00  145 29/32  145 30/32  145 28/32  145 29/32
2014-04-17 13:01:00  145 29/32        146  145 29/32        147
2014-04-17 13:02:00        146        146  145 30/32  145 31/32

Result:
2014-04-17 12:59:00  146.06250  146.0625  145.93750  145.93750
2014-04-17 13:00:00  145.90625  145.9375  145.87500  145.90625
2014-04-17 13:01:00  145.90625       146  145.90625        147
2014-04-17 13:02:00        146       146  145.93750  145.96875

【问题讨论】:

如果我没记错的话,Result = A.fillna(B) 应该这样做。 它有点工作,但前提是两个数据帧具有相同的索引(请参阅@Camilo 对 Foobar 答案的评论)。请注意,如果您只想用 B 中的非 NaN 值替换 A(即,用 B 中的现有值替换 A 中的值),A.update(b) 是完美的。 【参考方案1】:

官方推广的方式是A.combine_first(B)。更多信息在official documentation。

但是,它在使用来自 A.fillna(B) 的大型数据库(使用 25000 个元素执行测试)时表现出色:

In[891]: %timeit df.fillna(df2)
1000 loops, best of 3: 333 µs per loop
In[892]: %timeit df.combine_first(df2)
100 loops, best of 3: 2.15 ms per loop
In[894]: (df.fillna(df2) == df.combine_first(df2)).all().all()
Out[890]: True

【讨论】:

谢谢,combin_firs 的作品可以胜任。但是,fillna 不起作用,正在将 B 第一行与另一行中的 nan A 匹配 "fillna 不工作,正在将 B 第一行与另一行中的 nan A 匹配" > 使用相同的索引并为两者执行 df = df.sort_index()。【参考方案2】: 获取 A 和 B 的 numpy 数组。 制作 A 的掩码,其中 A == numpy.NaN 使用掩码作为布尔索引将 B 分配给 A。

与此类似:

>>> a
array([[  0.,   1.,   2.],
       [  3.,  nan,   5.],
       [  6.,   7.,   8.]], dtype=float16)
>>> b
array([[ 1000.,  1000.,  1000.],
       [ 1000.,  1000.,  1000.],
       [ 1000.,  1000.,  1000.]])
>>> mask = np.isnan(a)
>>> mask
array([[False, False, False],
       [False,  True, False],
       [False, False, False]], dtype=bool)
>>> a[mask] = b[mask]
>>> a
array([[    0.,     1.,     2.],
       [    3.,  1000.,     5.],
       [    6.,     7.,     8.]], dtype=float16)

或者,使用numpy.where():

>>> a
array([[  0.,   1.,   2.],
       [  3.,  nan,   5.],
       [  6.,   7.,   8.]], dtype=float16)
>>> a = np.where(np.isnan(a), b, a)
>>> a
array([[    0.,     1.,     2.],
       [    3.,  1000.,     5.],
       [    6.,     7.,     8.]])
>>>

https://***.com/a/13062410/2823755 建议第一个(布尔索引)方法可以与数据框本身一起使用。 ...确实如此(不满意,所以我安装了 pandas):

>>> a = pandas.DataFrame(np.arange(25, dtype = np.float16).reshape(5,5))
>>> a.values[3,2] = np.NaN
>>> b = pandas.DataFrame(np.arange(1000, 1025, dtype = np.float16).reshape(5,5))
>>> a[np.isnan(a)] = b[np.isnan(a)]
>>> a
    0   1     2   3   4
0   0   1     2   3   4
1   5   6     7   8   9
2  10  11    12  13  14
3  15  16  1017  18  19
4  20  21    22  23  24
>>> 

pandas.DataFrame.where 也可以。

a.where(~np.isnan(a), other = b, inplace = True)

【讨论】:

我也会尝试这个选项,因为 combine_first 花费了太多时间。您知道将数据帧转换为 numpy 数组的快速方法吗?再次感谢 对不起,没有。我没有安装 pandas 并且不熟悉它 - 但我认为它应该很容易,pandas 似乎广泛使用 numpy。 ***.com/a/17682662/2823755, pandas.pydata.org/pandas-docs/stable/generated/…, pandas.pydata.org/pandas-docs/stable/generated/…

以上是关于如何在熊猫中合并两个数据框以替换 nan的主要内容,如果未能解决你的问题,请参考以下文章

如何重新索引熊猫数据框以将起始索引值重置为零? [重复]

如何合并/组合熊猫中的列?

如何在熊猫中使用 python 循环替换缺失值? [关闭]

如何将用熊猫提取的一列excel数据中的NaN替换为0

如何在熊猫中用 NaN 替换浮点值?

如何在熊猫数据框中将单元格设置为 NaN