2017-10-06 2 views
1

j'ai des données par satellite qui ressemble à ce qui suit (diagramme de dispersion):scipy.stats.binned_statistic_2d travaille pour le comte, mais ne signifie pas

Night-time Ion Density

Je veux maintenant bin ces données dans une grille régulière sur le temps et la latitude et que chaque case soit égale à la moyenne de tous les points de données qui s'y trouvent. J'ai expérimenté avec scipy.stats.binned_statistic_2d et suis déconcerté par les résultats que je reçois. Premièrement, si je transmets la statistique "count" dans la fonction binning scipy, elle semble fonctionner correctement (code minimal et graphique ci-dessous).

id1 = np.ma.masked_where(id1==0, id1) #id1 is the actual data and I have tried using this masking argument and without to the same effect 

x_range = np.arange(0,24.25,.25) #setting grid spacing for x and y 
y_range = np.arange(-13,14,1) 

xbins, ybins = len(x_range), len(y_range) #number of bins in each dimension 

H, xedges, yedges, binnumber = stats.binned_statistic_2d(idtime, idlat, values = id1, statistic='count' , bins = [xbins, ybins]) #idtime and idlat are the locations of each id1 value in time and latitude 
H = np.ma.masked_where(H==0, H) #masking where there was no data 
XX, YY = np.meshgrid(xedges, yedges) 

fig = plt.figure(figsize = (13,7)) 
ax1=plt.subplot(111) 
plot1 = ax1.pcolormesh(XX,YY,H.T) 

résultant Terrain

Counts

Maintenant, si je change la statistique à dire, np.mean, np.ma.mean, etc ... c'est l'intrigue que je reçois qui semble choisir des endroits il y a des données et où il n'y a pas:

Mean

Même si les valeurs min et max pour ces données sont 612 et 223 7026 respectivement. J'ai écrit du code qui le fait manuellement, mais ce n'est pas joli et cela prend une éternité (et je n'ai pas complètement pris en compte les effets de bord, donc courir à l'erreur et ensuite le réparer prend une éternité).

J'aimerais avoir quelques conseils pour que cela fonctionne. Merci! Edit: Je viens de remarquer que je reçois un avertissement d'exécution après l'exécution du script que je ne trouve pas d'informations sur en ligne. Une recherche google pour l'avertissement ne renvoie aucun résultat. L'avertissement se produit pour chaque option statistique, sauf pour le nombre.

AppData \ Local \ Enthought \ Canopy \ électroérosion \ envs \ User \ lib \ site-packages \ matplotlib \ colors.py: 494: RuntimeWarning: valeur non valide rencontrée en moins cbook._putmask (xa, xa < 0.0, -1)

Édition2: Je joins un code ci-dessous qui reproduit mon problème. Ce code fonctionne pour le nombre de statistiques mais pas pour la moyenne ou toute autre statistique. Ce code produit le même avertissement d'exécution d'avant de la même manière.

import matplotlib.pyplot as plt 
import numpy as np 
from scipy import stats 

x = np.random.rand(1000) 
y = np.random.rand(1000) 

z = np.arange(1000) 

H, xedges, yedges, binnumber = stats.binned_statistic_2d(x, y, values = z, statistic='count' , bins = [20, 20]) 
H2, xedges2, yedges2, binnumber2 = stats.binned_statistic_2d(x, y, values = z, statistic='mean' , bins = [20, 20]) 

XX, YY = np.meshgrid(xedges, yedges) 
XX2, YY2 = np.meshgrid(xedges2, yedges2) 

fig = plt.figure(figsize = (13,7)) 
ax1=plt.subplot(111) 
plot1 = ax1.pcolormesh(XX,YY,H.T) 
cbar = plt.colorbar(plot1,ax=ax1, pad = .015, aspect=10) 
plt.show() 

fig2 = plt.figure(figsize = (13,7)) 
ax2=plt.subplot(111) 
plot2 = ax2.pcolormesh(XX2,YY2,H2.T) 
cbar = plt.colorbar(plot2,ax=ax2, pad = .015, aspect=10) 
plt.show() 

count_working_code mean_working_code

Edit 3: User8153 a pu identifier le problème. La solution était de masquer le tableau des statistiques scipy où les nans se produisent. J'ai utilisé np.ma.masked_invalid() pour ce faire. Les graphiques de mes données d'origine et de test sont inférieurs à la statistique moyenne.

Working Mean My Data Working Mean Sample Data

+0

Lorsque vous utilisez les ' 'statistiques de count'' vous masque les éléments de' H' qui ont le nombre 0, soit il n'y a pas de données . Selon les docs de 'binned_statistic_2d', les cases vides sont représentées par' NaN' quand on change les statistiques en ''mean' 'ou'' median''. Avez-vous essayé de changer le masque pour filtrer ces 'NaN's? – user8153

+0

Peut-être pertinent: https://github.com/matplotlib/matplotlib/issues/6069/ – user8153

+1

avez-vous vérifié les valeurs NA? vous n'avez pas fourni vos données, donc pas reproductible. – denfromufa

Répondre

1

Lorsque vous utilisez les statistiques 'count' dans binned_statistic_2d bacs vides sont marqués comme zéro, ce qui vous masque dans votre code. Si vous passez aux statistiques 'mean' ou 'median' alors les cases vides sont représentées par NaN, vous devez donc ajuster le masque pour cela.Une façon de le faire est de remplacer

H = np.ma.masked_where(H==0, H) 

par

H = np.ma.masked_invalid(H)