2015-08-04 19 views
6

UPDATE (L'errore vera)

ho erroneamente identificato dove l'errore venisse. Qui è la mia funzione nella sua interezza (scusate se alcune delle linee sono oscure e confuse ...)numpy "Mean of empty slice". avvertimento

def removeLines(input,CRVAL1,CDELT1): #Masks out the Balmer lines from the spectrum 
    #Numbers 4060, 4150, 4300, 4375, 4800, and 4950 obtained from fit_RVs.pro. 
    #Other numbers obtained from the Balmer absorption series lines 

    for i in range(0,len(lineWindows),2): 
     left = toIndex(lineWindows[i],CRVAL1,CDELT1) 
     right = toIndex(lineWindows[i+1],CRVAL1,CDELT1) 

     print "left = ", left 
     print "right = ", right 
     print "20 from right =\n", input[right:right+20] 
     print "mean of 20 = ", numpy.mean(input[right:right+20]) 

     #Find the averages on the left and right sides 
     left_avg = numpy.mean(input[left-20:left]) 
     right_avg = numpy.mean(input[right:right+20]) #<--- NOT here 

     print "right_avg = ", right_avg 

     #Find the slope between the averages 
     slope = (left_avg - right_avg)/(left - right) 

     #Find the y-intercept of the line conjoining the averages 
     bval = ((left_avg - slope*left) + (right_avg - slope*right))/2 

     for j in range(left,right):  #Redefine the data to follow the line conjoining 
      input[j] = slope*j + bval #the sides of the peaks 

    left = int(input[0]) 
    left_avg = int(input[0]) 
    right = toIndex(lineWindows[0],CRVAL1,CDELT1) 
    right_avg = numpy.mean(input[right:right+20]) #<---- THIS IS WHERE IT IS! 
    slope = (left_avg - right_avg)/(left - right) 
    bval = ((left_avg - slope*left) + (right_avg - slope*right))/2 

    for i in range(left, right): 
     input[i] = slope*i + bval 
    return input 

Ho studiato il problema e trovato la risposta, che viene pubblicato qui di seguito (non in questo post).


L'errore (La sciocca falso errore)

#left = An index in the data (on the 'left' side) 
#right = An index in the data (on the 'right' side) 
#input = The data array 

print "left = ", left 
print "right = ", right 
print "20 from right =\n", input[right:right+20] 
print "mean of 20 = ", numpy.mean(input[right:right+20]) 

#Find the averages on the left and right sides 
left_avg = numpy.mean(input[left-20:left]) 
right_avg = numpy.mean(input[right:right+20]) 

ha prodotto l'uscita

left = 1333 
right = 1490 
20 from right = 
[ 0.14138737 0.14085886 0.14038289 0.14045525 0.14078836 0.14083192 
    0.14072289 0.14082283 0.14058594 0.13977806 0.13955595 0.13998236 
    0.1400764 0.1399636 0.14025062 0.14074247 0.14094831 0.14078569 
    0.14001536 0.13895717] 
mean of 20 = 0.140395 
Traceback (most recent call last): 
... 
    File "getRVs.py", line 201, in removeLines 
    right_avg = numpy.mean(input[right:right+20]) 
    File "C:\Users\MyName\Anaconda\lib\site-packages\numpy\core\fromnumeric.py", line 2735, in mean 
    out=out, keepdims=keepdims) 
    File "C:\Users\MyName\Anaconda\lib\site-packages\numpy\core\_methods.py", line 59, in _mean 
    warnings.warn("Mean of empty slice.", RuntimeWarning) 
RuntimeWarning: Mean of empty slice. 

sembrerebbe che numpy.mean viene eseguito correttamente quando stampo, ma in modo diverso quando ho assegnarlo a un valore. Qualsiasi feedback sarebbe molto apprezzato. Grazie per aver dedicato del tempo a leggere la mia domanda.


Breve spiegazione

Insomma, sto scrivendo un codice per gestire dati scientifici e parte del codice consiste nel prendere la media di circa 20 valori.

#left = An index in the data (on the 'left' side) 
#right = An index in the data (on the 'right' side) 
#input = The data array 

#Find the averages on the left and right sides 
left_avg = numpy.mean(input[left-20:left]) 
right_avg = numpy.mean(input[right:right+20]) 

Questo codice restituisce una "media della porzione vuota" numerica. avvertimento e fastidiosamente lo stampa nella mia preziosa produzione! Ho deciso di provare a rintracciare la fonte della segnalazione come visto here, per esempio, così ho messo

import warnings 
warnings.simplefilter("error") 

nella parte superiore del mio codice, che poi ha restituito il seguente Traceback snipped:

File "getRVs.py", line 201, in removeLines 
    right_avg = numpy.mean(input[right:right+20]) 
    File "C:\Users\MyName\Anaconda\lib\site-packages\numpy\core\fromnumeric.py", line 2735, in mean 
    out=out, keepdims=keepdims) 
    File "C:\Users\MyName\Anaconda\lib\site-packages\numpy\core\_methods.py", line 59, in _mean 
    warnings.warn("Mean of empty slice.", RuntimeWarning) 
RuntimeWarning: Mean of empty slice. 

Ho omesso circa i 2/3 di Traceback perché passa attraverso circa 5 funzioni difficili da spiegare che non influiscono sulla leggibilità o sulla dimensione dei dati.

così ho deciso di stampare l'intera operazione per vedere se davvero right_avg stava tentando un numpy.mean di una fetta vuota ... E che quando le cose sono davvero strano.

+1

L'errore sta dicendo che la seconda volta '' numpy.mean (input [right: right + 20]) 'viene chiamato,' input [right: right + 20] 'è vuoto. Ci deve essere un codice tra la prima e la seconda chiamata che sta cambiando il valore di 'input'. – unutbu

+0

I valori per 'input' ** sono ** modificati come hai detto, ma non c'è errore quando stampo lo stesso codice prima ancora che venga chiamato. Pensi che sia un problema con come sto assegnando 'left_avg'? – boof

+0

Avevi ragione! C'è una parte del codice più avanti nella stessa funzione che gestisce 'right_avg'! Ho aggiornato il thread principale per evitare di sprecare il tempo delle persone. Che imbarazzo ... – boof

risposta

3

You dingbat! La risposta è ovvia, vero ?? Hai chiaramente erroneamente identificato la riga di codice su cui si è verificato il tuo errore. Quello che devi fare è scrivere nel codice per il caso specifico in cui la finestra (left e right lati) attorno al punto centrale considerato nei dati è troppo vicino al bordo dell'array di dati.

def removeLines(input,CRVAL1,CDELT1): #Masks out the Balmer lines from the spectrum 

    for i in range(0,len(lineWindows),2): 
     left = toIndex(lineWindows[i],CRVAL1,CDELT1) 
     right = toIndex(lineWindows[i+1],CRVAL1,CDELT1) 

     #Find the averages on the left and right sides 
     left_avg = numpy.mean(input[left-20:left]) 
     right_avg = numpy.mean(input[right:right+20]) 

     #Find the slope between the averages 
     slope = (left_avg - right_avg)/(left - right) 

     #Find the y-intercept of the line conjoining the averages 
     bval = ((left_avg - slope*left) + (right_avg - slope*right))/2 

     for j in range(left,right):  #Redefine the data to follow the line conjoining 
      input[j] = slope*j + bval #the sides of the peaks 

    left = 0 
    left_avg = int(input[0]) 

    if toIndex(lineWindows[0],CRVAL1,CDELT1) < 0: right = 0 
    else: right = toIndex(lineWindows[0],CRVAL1,CDELT1) 

    right_avg = numpy.mean(input[right:right+20]) 
    slope = (left_avg - right_avg)/(left - right) 
    bval = ((left_avg - slope*left) + (right_avg - slope*right))/2 

    for i in range(left, right): 
     input[i] = slope*i + bval 
    return input 

semplicemente cambiare questa

right = toIndex(lineWindows[0],CRVAL1,CDELT1) #Error occurs where right = -10 
right_avg = numpy.mean(input[right:right+20]) #Index of -10? Yeah, right. 

a questo

if toIndex(lineWindows[0],CRVAL1,CDELT1) < 0: right = 0 #Index 0, much better! 
else: right = toIndex(lineWindows[0],CRVAL1,CDELT1) #Leave it alone if it isn't a problem. 

right_avg = numpy.mean(input[right:right+20]) 

Inoltre, eri totalmente sbagliato su left = int(input[0]), quindi l'ho cambiato per left = 0 per voi. Chi conosce quali altri semplici errori produce questo codice sciatto e sciatto? Guarda un po 'più difficile prima di postare su Stack Overflow, per favore!

1

Non è stato possibile riprodurre l'errore. Stai usando l'ultima versione di Numpy? Tuttavia si potrebbe sopprimere gli avvertimenti da parte Uding la parola ignorare (vedi https://docs.python.org/2/library/warnings.html#temporarily-suppressing-warnings)

Questo errore normalmente significa che una lista vuota è stato passato alla funzione.

>>> a = [] 

>>> import numpy 
>>> numpy.mean(a) 
/shahlab/pipelines/apps_centos6/Python-2.7.10/lib/python2.7/site-packages/numpy/core/_methods.py:59: RuntimeWarning: Mean of empty slice. 
    warnings.warn("Mean of empty slice.", RuntimeWarning) 
/shahlab/pipelines/apps_centos6/Python-2.7.10/lib/python2.7/site-packages/numpy/core/_methods.py:71: RuntimeWarning: invalid value encountered in double_scalars 
    ret = ret.dtype.type(ret/rcount) 
nan 
>>> print numpy.mean(a) 
nan 

>>> import warnings 
>>> warnings.simplefilter("ignore") 
>>> numpy.mean(a) 
nan 

>>> a=[ 0.14138737, 0.14085886, 0.14038289, 0.14045525, 0.14078836, 0.14083192, 0.14072289, 0.14082283, 0.14058594, 0.13977806, 0.13955595, 0.13998236, 0.1400764, 0.1399636, 0.14025062, 0.14074247, 0.14094831, 0.14078569, 0.14001536, 0.13895717] 
>>> numpy.mean(a) 
0.140394615 
>>> x = numpy.mean(a) 
>>> print x 
0.140394615 
>>> numpy.__version__ 
'1.9.2' 

Speranza che aiuta.

+0

Grazie per il risposta! Ho provato a sopprimere gli avvertimenti all'inizio, ma poi una piccola bandiera rossa è esplosa nella mia testa. Mi sto occupando di dati _scientific_ qui, il che significa che è un grosso problema se il mio codice sta elaborando una lista vuota per un motivo sconosciuto. Quando sono andato a controllarlo, la lista era ** non ** vuota come mi aveva detto che era! Quindi ora sto cercando di capire perché Numpy sta facendo questo. Sto anche usando la versione numpy 1.9.2. – boof

+0

Questo è strano. Il codice non cambia la lista "input". È possibile pubblicare il codice che può riprodurre questo errore (forse con un elenco di input più piccolo)? Proverò con alcuni dati fittizi per vedere se riesco a ottenere lo stesso errore. – Diljot

+0

Ho appena aggiornato il post principale. Ho totalmente preso in giro e identificato la riga di codice errata come l'errore. Quello che sto guardando in questo momento sta rendendo molto più sensato il motivo per cui l'avvertimento sta accadendo. Scusate! – boof