2016-03-02 31 views
5

Ho una matrice con forma (64,17) corrisponde al tempo & latitudine. Voglio prendere una media ponderata della latitudine, che so che np.average può fare perché, a differenza di np.nanmean, che ho usato per mediare le longitudini, i pesi possono essere usati negli argomenti. Tuttavia, np.average non ignora NaN come fa np.nanmean, quindi le mie prime 5 voci di ogni riga sono incluse nella media della latitudine e rendono l'intera serie storica piena di NaN.Prendendo np.average ignorando NaN?

C'è un modo per prendere una media ponderata senza che i NaN vengano inclusi nel calcolo?

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[:] 

uscita:

[ 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] 

risposta

4

È possibile creare una matrice mascherato come questo:

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

This uscite:

[ 2. 4.5 6. 0. ] 
+0

Ho detto che non posso usare np.nanmean perché non prende i pesi nei suoi argomenti. Sto cercando di fare una media ponderata. – ChristineB

+0

Ho aggiornato la risposta per utilizzare un array mascherato e 'np.mean' – Jaco

+0

Stavo per modificare una menzione nel post originale che dal momento che sto facendo una serie temporale, rimuovere il NaN dai dati è anche un'opzione, ma mi hai battuto per questo! – ChristineB

3

Si può semplicemente moltiplicare la matrice di ingresso con il weights e la somma lungo l'asse specificato ignorando NaNs con np.nansum. Così, per il caso, assumendo la weights devono essere utilizzati lungo axis = 1 sull'array ingresso sst_filt, sarebbe -

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

Per un caso generico, una funzione potrebbe essere definita come segue -

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

corsa del campione -

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

probabilmente sarei basta selezionare la porzione di matrice che non è Nan e quindi utilizzare tali indici per selezionare la Weig anche lui.

Ad esempio:

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 

Edit: ho capito che questo non funzionerà con due array bidimensionali. In tal caso, probabilmente dovrei semplicemente impostare i valori e i pesi a zero per i NaN. Questo produce lo stesso risultato come se quegli indici non fossero stati inclusi nel calcolo.

Prima np.average esecuzione:

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

O creare copie se si desidera tenere traccia di cui gli indici erano NaN.