【问题标题】:Comparing NumPy arrays so that NaNs yield NaNs比较 NumPy 数组以便 NaN 产生 NaN
【发布时间】:2021-06-04 10:34:21
【问题描述】:
import numpy as np

我有两个数组:

a = np.array([1,2,3,np.nan,5])
b = np.array([3,2,np.nan,5,4])

我想比较这两个数组中的元素并得到一个布尔值列表作为结果。当有nan参与比较时,我想得到nan。预期结果:

[False, False, nan, nan, True]

我使用if-else involving list comprehension 实现了所需的输出:

[eacha>eachb
 if ~np.isnan(eacha) and ~np.isnan(eachb)
 else np.nan
 for eacha, eachb in zip(a,b)]

有没有更好的方法(即不涉及 for 循环、if-else 语句)?

【问题讨论】:

  • np.where(np.isnan(a * b), np.nan, a==b) 应该比给定的答案更快,因为它避免了不必要的第三次操作。由于 NaN 乘以任何东西都等于 NaN,我们可以使用乘法而不是最后的 or
  • 如果您只关心最终结果中的真假,您可以使用(a * b) * (a == b) 加快速度
  • 你能详细说明一下吗?我想在我的数组中有 True-s 和 False-s,而不是浮点数。
  • @zabop 如果你想要nans 那么你必须使用浮点数据类型
  • 为什么 nan 的数据类型必须强加于整个数组,为什么我不能有 float nans 和 boolean Trues Falses?

标签: python numpy


【解决方案1】:

你可以试试:

np.where(np.isnan(a)|np.isnan(b), np.nan, a==b)

但是你得到一个浮点数组,因为np.nan 是浮点数:

array([ 0.,  1., nan, nan,  0.])

【讨论】:

  • 谢谢。如果你能建议一种方法让 0.s False 和 1.s True,那就太棒了(添加了这样的方法,但显然这不是那么好)。
【解决方案2】:

要将Quang Hoangexcellent answer 的输出从浮点数更改为布尔值,我们可以使用pandas.Series.replace

pd.Series(np.where(np.isnan(a)|np.isnan(b), np.nan, a==b)).replace({0:False,1:True}).to_numpy()

导致:

0    False
1     True
2      NaN
3      NaN
4    False
dtype: object

或:

pd.Series(np.where(np.isnan(a)|np.isnan(b), np.nan, a==b)).replace({0:False,1:True}).to_numpy()

导致:

array([False, True, nan, nan, False], dtype=object)

【讨论】:

  • 不是我的反对意见,但这根本不是改进。
  • 谢谢。编辑了这篇文章,所以现在没有提到改进,只是结果是布尔值,而不是浮点数。
  • @zabop 不,结果 id dtype=object 通常很糟糕。这样你就失去了numpy 的优势。这可能不是仅使用常规 python 列表和循环的改进。 dtype=object numpy 数组基本上是一个性能较差的 python 列表。顺便说一句,我没有投反对票,但这可能解释了对这个答案的普遍厌恶
  • 就我而言,性能不是问题。我正在创建的数据框的可读性是。这就是为什么我需要 Trues 和 Falses,而不是浮点数。感谢您的评论,它很有用。
猜你喜欢
  • 2012-06-04
  • 2021-06-20
  • 2019-02-25
  • 2016-05-26
  • 2014-07-11
  • 1970-01-01
  • 2014-10-10
相关资源
最近更新 更多