在忽略NaN的情况下采用np.average?

时间:2016-03-02 21:12:10

标签: python numpy latitude-longitude weighted-average

我有一个形状矩阵(64,17)对应时间&纬度。我想采用加权纬度平均值,我知道np.average可以做,因为,与我用来平均经度的np.nanmean不同,权重可以用在参数中。但是,np.average并不像np.nanmean那样忽略NaN,所以每行的前5个条目都包含在纬度平均值中,并使整个时间序列充满NaN。

如果计算中不包含NaN,有没有办法可以采用加权平均值?

file = Dataset("sst_aso_1951-2014latlon_seasavgs.nc")
sst = file.variables['sst']
lat = file.variables['lat']

sst_filt = np.asarray(sst)
missing_values_indices = sst_filt < -8000000   #missing values have value -infinity
sst_filt[missing_values_indices] = np.nan      #all missing values set to NaN

weights = np.cos(np.deg2rad(lat))
sst_zonalavg = np.nanmean(sst_filt, axis=2)
print sst_zonalavg[0,:]
sst_ts = np.average(sst_zonalavg, axis=1, weights=weights)
print sst_ts[:]

输出:

[ nan nan nan nan nan
 27.08499908 27.33333397 28.1457119 28.32899857 28.34454346
 28.27285767 28.18571472 28.10199928 28.10812378 28.03411865
 28.06411552 28.16529465]

[ nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
 nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
 nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
 nan nan nan nan]

4 个答案:

答案 0 :(得分:11)

你可以像这样创建一个蒙面数组:

data = np.array([[1,2,3], [4,5,np.NaN], [np.NaN,6,np.NaN], [0,0,0]])
masked_data = np.ma.masked_array(data, np.isnan(data))
# calculate your weighted average here instead
weights = [1, 1, 1]
average = np.ma.average(masked_data, axis=1, weights=weights)
# this gives you the result
result = average.filled(np.nan)
print(result)

输出:

[ 2.   4.5  6.   0. ]

答案 1 :(得分:3)

您可以简单地将输入数组与weights相乘,并沿指定的轴求和,忽略NaNs np.nansum。因此,对于您的情况,假设要在输入数组weights上的axis = 1上使用sst_filt,它将是 -

np.nansum(sst_filt*weights,axis=1)

对于一般情况,函数可以定义如下 -

def nanaverage(A,weights,axis):
    return np.nansum(A*weights,axis=axis)

示例运行 -

In [200]: sst_filt  # 2D array case
Out[200]: 
array([[  0.,   1.],
       [ nan,   3.],
       [  4.,   5.]])

In [201]: weights
Out[201]: array([ 0.25,  0.75])

In [202]: nanaverage(sst_filt,weights=weights,axis=1)
Out[202]: array([ 0.75,  2.25,  4.75])

答案 2 :(得分:3)

我可能只是选择不是NaN的数组部分,然后使用这些索引来选择权重。

例如:

import numpy as np
data = np.random.rand(10)
weights = np.random.rand(10)
data[[2, 4, 8]] = np.nan

print data
# [ 0.32849204,  0.90310062,         nan,  0.58580299,         nan,
#    0.934721  ,  0.44412978,  0.78804409,         nan,  0.24942098]

ii = ~np.isnan(data)
print ii
# [ True  True False  True False  True  True  True False  True]

result = np.average(data[ii], weights = weights[ii])
print result
# .6470319

编辑:我意识到这不会适用于二维数组。在这种情况下,我可能只是为NaN设置值和权重为零。这产生了相同的结果,就好像这些指数不包括在计算中一样。

在运行np.average之前:

data[np.isnan(data)] = 0;
weights[np.isnan(data)] = 0;
result = np.average(data, weights=weights)

如果您想跟踪哪些指数是NaN,请创建副本。

答案 3 :(得分:1)

@deto

第一行将删除所有nan,这将导致第二行具有错误的结果。

data[np.isnan(data)] = 0;
weights[np.isnan(data)] = 0;
result = np.average(data, weights=weights)

在运行第一行之前应复制一份

data_copy = copy.deepcopy(data)
data[np.isnan(data_copy)] = 0;
weights[np.isnan(data_copy)] = 0;
result = np.average(data, weights=weights)
相关问题