我想明智地添加数千个4D数组元素,并考虑到nans。 使用1D数组的一个简单示例是:
X = array([4,7,89,nan,89,65, nan])
Y = array([0,5,4, 9, 8, 100,nan])
z = X+Y
print z = array([4,12,93,9,97,165,nan])
我已经为此编写了一个简单的for循环,但它需要永远 - 而不是一个聪明的解决方案。 另一个解决方案可能是创建一个更大的阵列并使用瓶颈nansum,但这会占用我的笔记本电脑太多的内存。我需要超过11000个案件的总和。
有没有人有聪明而快速的方法来做到这一点?
答案 0 :(得分:10)
这是一种可能性:
>>> x = np.array([1, 2, np.nan, 3, np.nan, 4])
... y = np.array([1, np.nan, 2, 5, np.nan, 8])
>>> x = np.ma.masked_array(np.nan_to_num(x), mask=np.isnan(x) & np.isnan(y))
>>> y = np.ma.masked_array(np.nan_to_num(y), mask=x.mask)
>>> (x+y).filled(np.nan)
array([ 2., 2., 2., 8., nan, 12.])
真正的困难是你似乎希望nan
被解释为零,除非特定位置的所有值都是nan
。这意味着您必须同时查看x和y以确定要替换的nans。如果您可以替换所有的nan值,那么您只需执行np.nan_to_num(x) + np.nan_to_num(y)
。
答案 1 :(得分:3)
您可以执行以下操作:
arr1 = np.array([1.0, 1.0, np.nan, 1.0, 1.0, np.nan])
arr2 = np.array([1.0, 1.0, 1.0, 1.0, 1.0, np.nan])
flags = np.isnan(arr1) & np.isnan(arr2)
copy1 = arr1.copy()
copy2 = arr2.copy()
copy1[np.isnan(copy1)] = 0.0
copy2[np.isnan(copy2)] = 0.0
out = copy1 + copy2
out[flags] = np.NaN
print out
array([ 2., 2., 1., 2., 2., NaN])
查找数组中位于该索引中的NaN
的位置。然后,基本上做@mgilson建议的内容,如在make copy中用0.0替换NaN
s,将两个数组加在一起,然后用np.NaN
替换上面标记的索引。
答案 2 :(得分:3)
import numpy as np
z=np.nansum([X,Y],axis=0)
答案 3 :(得分:1)
不确定这会如何表现,但值得一试:)
def nan_to_zero(array):
new_arr = array.copy()
new_arr[np.isnan(array)] = 0.
return new_arr
sum( nan_to_zero(arr) for arr in array_generator )
但这不会导致数组最后一个位置NaN
。它导致0 ...
答案 4 :(得分:1)
我看到了几个更简单的解决方案:
(已编辑)使用np.ma
mX = np.ma.masked_array(X, mask=np.isnan(X))
mY = np.ma.masked_array(Y, mask=np.isnan(Y))
mZ = np.ma.masked_array(mX.filled(0) + mY.filled(0),
mask=mX.mask * mY.mask)
Z = mZ.filled(np.nan)
(已编辑)未使用np.ma
mx = np.isnan(x)
my = np.isnan(y)
z = np.where(mx,0,x) + np.where(my,0,y)
z[mx&my] = np.nan