我有两个4D矩阵,我想补充一下。矩阵具有完全相同的维度和元素数量,但它们都包含随机分布的NaN值。
我更愿意使用numpy.nansum将它们添加如下
(1)如果添加两个值,我希望总和为值,
(2)如果加上一个值和一个NaN,我希望总和为值和
(3)如果加入两个NaN,我希望总和为NaN。
此处我尝试了什么
a[6x7x180x360]
b[6x7x180x360]
C=np.nansum[(a,b)]
C=np.nansum(np.dstack((a,b)),2)
但是我无法得到与输入相同维度的结果矩阵。这意味着结果矩阵C应该在[6x7x180x360]中。 在这方面任何人都可以提供帮助提前谢谢。
答案 0 :(得分:4)
您可以使用np.stack((a,b))
沿新的0轴堆叠,然后调用nansum
沿该0轴求和:
C = np.nansum(np.stack((a,b)), axis=0)
例如,
In [34]: a = np.random.choice([1,2,3,np.nan], size=(6,7,180,360))
In [35]: b = np.random.choice([1,2,3,np.nan], size=(6,7,180,360))
In [36]: np.stack((a,b)).shape
Out[36]: (2, 6, 7, 180, 360)
In [37]: np.nansum(np.stack((a,b)), axis=0).shape
Out[37]: (6, 7, 180, 360)
你有正确的想法,但np.dstack
沿着第三轴堆叠,这是不可取的,因为你已经有4个轴:
In [31]: np.dstack((a,b)).shape
Out[31]: (6, 7, 360, 360)
关于你的观点(3):
请注意np.nansum
depends on the NumPy version的行为:
在NumPy版本中< = 1.8.0,对于全NaN或切片,返回Nan 空。在以后的版本中,返回零。
如果您使用的是NumPy版本> 1.8.0,那么您可能必须使用solution such as Maarten Fabré's来解决此问题。
答案 1 :(得分:1)
我认为最简单的方法是使用np.where
result = np.where(
np.isnan(a+b),
np.where(np.isnan(a), b, a),
a+b
)
这读作:
如果a+b
不是nan
,请使用a+b
,否则使用a
,除非是nan
,然后使用b
。或者b
是nan
是不是很重要。
或者,您可以像这样使用它:
result2 = np.where(
np.isnan(a) & np.isnan(b),
np.nan,
np.nansum(np.stack((a,b)), axis=0)
)
np.testing.assert_equal(result, result2)
通过
答案 2 :(得分:0)
我认为函数np.nansum不适合你的情况。如果我正确地理解了你的问题,你希望在元素方面添加两个矩阵,其中有一些关于NaN值的逻辑。
以下是有关如何操作的完整示例:
import numpy as np
a = np.array([ [np.nan, 2],
[3, np.nan]])
b = np.array([ [3, np.nan],
[1, np.nan]])
result = np.add(a,b)
a_is_nan = np.isnan(a)
b_is_nan = np.isnan(b)
result_is_nan = np.isnan(result)
mask_a = np.logical_and(result_is_nan, np.logical_not(a_is_nan))
result[mask_a] = a[mask_a]
mask_b = np.logical_and(result_is_nan, np.logical_not(b_is_nan))
result[mask_b] = b[mask_b]
print(result)
一点点解释:
第一个操作是np.add(a,b)。这会添加两个矩阵,任何NaN元素也会产生NaN的结果。
要从任一数组中选择NaN值,我们使用逻辑掩码:
# result_is_nan is a boolean array containing True whereve the result is np.NaN. This occurs when any of the two element were NaN
result_is_nan = np.isnan(result)
# mask_a is a boolean array which 'flags' elements that are NaN in result but were not NaN in a !
mask_a = np.logical_and(result_is_nan, np.logical_not(a_is_nan))
# Using that mask, we assign those value to result
result[mask_a] = a[mask_a]
你有它!