如何仅用Numpy合并含numpy.NaN的布尔数组?
问题:仅用Numpy合并布尔数组与含NaN的布尔数组
现有两个Numpy数组:
- 第一个数组
a1仅包含布尔值True/False - 第二个数组
a2的元素可以是True、False,也可以是numpy.NaN
需要按以下规则合并两个数组:若a2对应位置的值为numpy.NaN,则取a1对应位置的值;否则取a2的布尔值。已知通过循环可实现该需求,询问能否仅使用Numpy完成此计算?
示例代码
# 示例1 a1 = np.array([True, False, True, False, True], dtype=object) a2 = np.array([np.NaN, np.NaN, np.NaN, np.NaN, np.NaN], dtype=object) output = a1.combinaficate(a2) # 输出: [True, False, True, False, True] # 示例2 a1 = np.array([True, False, True, False, True], dtype=object) a2 = np.array([np.NaN, True, np.NaN, False, np.NaN], dtype=object) output = a1.combinaficate(a2) # 输出: [True, True, True, False, True] # 示例3 a1 = np.array([True, True, True, True, True], dtype=object) a2 = np.array([np.NaN, np.NaN, np.NaN, False, np.NaN], dtype=object) output = a1.combinaficate(a2) # 输出: [True, True, True, False, True] # 示例4 a1 = np.array([False, False, False, False, False], dtype=object) a2 = np.array([np.NaN, np.NaN, True, False, np.NaN], dtype=object) output = a1.combinaficate(a2) # 输出: [False, False, True, False, False]
纯Numpy实现方案
完全可以用Numpy原生方法实现,核心利用NaN不等于自身的特性生成掩码,结合np.where完成值的替换:
import numpy as np def combinaficate(a1, a2): # 生成掩码:标记a2中所有NaN的位置 nan_mask = a2 != a2 # 按规则合并数组 return np.where(nan_mask, a1, a2) # 测试示例1 a1 = np.array([True, False, True, False, True], dtype=object) a2 = np.array([np.NaN, np.NaN, np.NaN, np.NaN, np.NaN], dtype=object) print(combinaficate(a1, a2)) # [True False True False True] # 测试示例2 a1 = np.array([True, False, True, False, True], dtype=object) a2 = np.array([np.NaN, True, np.NaN, False, np.NaN], dtype=object) print(combinaficate(a1, a2)) # [True True True False True] # 测试示例3 a1 = np.array([True, True, True, True, True], dtype=object) a2 = np.array([np.NaN, np.NaN, np.NaN, False, np.NaN], dtype=object) print(combinaficate(a1, a2)) # [True True True False True] # 测试示例4 a1 = np.array([False, False, False, False, False], dtype=object) a2 = np.array([np.NaN, np.NaN, True, False, np.NaN], dtype=object) print(combinaficate(a1, a2)) # [False False True False False]
原理说明
nan_mask = a2 != a2:NaN的特性是与任何值比较都不相等(包括自身),因此这条语句会生成一个布尔掩码,其中a2为NaN的位置对应True,其他位置对应False。np.where(nan_mask, a1, a2):遍历数组每个位置,若掩码为True(即a2对应位置是NaN),则取a1的值;否则取a2的值,完全符合需求。
内容的提问来源于stack exchange,提问作者Shmack
相关产品推荐
相关产品推荐

