steve
steve

Reputation: 531

TypeError: slice indices must be integers or None or have an __index__ method on float number time series

I am working with some NetCDF files. In order to produce readable plots, I wish to smooth daily data over long time periods. I did this small function for that:

def mov_avg(x,window,min_count=None,axis=-1):
    import bottleneck as bn

    yy=np.ma.filled(np.ma.fix_invalid(x),np.nan)
    yyF=np.ma.masked_all(yy.shape)
    xtmp=bn.move_mean(yy,window,min_count=min_count,axis=axis)
    wd1=(window-1)/2
    ndim = len(yy.shape)
    #print xtmp.shape,ndim,axis,window,wd1
    if ndim ==1 :
    #print wd1,-wd1,wd-1
         yyF[wd1:-wd1]=np.ma.fix_invalid(xtmp[window-1:])

    elif ndim == 2:
        if axis==-1 or axis==1:
            yyF[:,wd1:-wd1]=np.ma.fix_invalid(xtmp[:,window-1:])
        elif axis==0:
            yyF[wd1:-wd1,:]=np.ma.fix_invalid(xtmp[window-1:,:])

    return yyF

unfortunately when I use this function on one of my variable times series as in the following code:

for station in stations:
    for variable in variables:
        os.chdir(inbasedir + variable + "_albedomodis2/")
        albmerge = "%s/%s_%s_merged.nc"%(inbasedir + variable + "_albedomodis2/",station,variable)
        albnc = Dataset(albmerge, 'r+')
        obs = albnc.variables[variable + '_obs'][:,0,0]
        obs_smooth = mov_avg(obs,7)

I got the following error message:

    TypeError                                 Traceback (most recent call last)
<ipython-input-10-025f4573f745> in <module>()
     12         ctessel_alb = albnc.variables[variable + '_ctessel'][:,0,0]
     13 
---> 14         obs_smooth = mov_avg(obs,7)
     15 
     16 

<ipython-input-3-c01b37a40c9a> in mov_avg(x, window, min_count, axis)
     10     if ndim ==1 :
     11     #print wd1,-wd1,wd-1
---> 12         yyF[wd1:-wd1]=np.ma.fix_invalid(xtmp[window-1:])
     13 
     14     elif ndim == 2:

/home/david/anaconda3/lib/python3.6/site-packages/numpy/ma/core.py in __setitem__(self, indx, value)
   3351         elif not self._hardmask:
   3352             # Set the data, then the mask
-> 3353             _data[indx] = dval
   3354             _mask[indx] = mval
   3355         elif hasattr(indx, 'dtype') and (indx.dtype == MaskType):

TypeError: slice indices must be integers or None or have an __index__ method

Yes obviously my data is not integer... Does anyone knows how to overcome this error?

Upvotes: 0

Views: 475

Answers (1)

sreveryn
sreveryn

Reputation: 107

I think I figured it out. I haven't tested it for Python 2 yet but I think I know why it doesn't work in Python 3.

In your first code block defining the function mov_avg your first two arguments are x and window. In the function you have the line:

wd1=(window-1)/2

When you call the function you call it as:

obs_smooth = mov_avg(obs,7)

where window=7. Within the function body wd1 is calculated, but it doesn't evaluate to 3, it evaluates to 3.0 - a float value, not an integer. So when it tries to do the line starting with yyF[:,wd1:-wd1], it fails because wd1 isn't an integer.

You could try to use the int() function to convert it to a float.

I tested accessing a sample list using float and integer values on a default installation of Python 3.6.5 installed using Conda.

Python 3.6.5 |Anaconda, Inc.| (default, Mar 29 2018, 13:32:41) [MSC v.1900 64 bit 
(AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> a = [1,2,3,4,5]
>>> a[0], a[4]
(1, 5)
>>> a[0.0,4]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: list indices must be integers or slices, not tuple

And in the specific case of your code:

>>> window = 7
>>> wd1 = (window-1)/2
>>> wd1
3.0
>>> a[wd1]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: list indices must be integers or slices, not float

EDIT: In Python 2, the result of the last operation would be an integer, not a float. Perhaps this is why it is working on Python 2 but not Python 3?

Disclaimer: I'm new to programming so if this isn't the reason, sorry! I'm trying to learn more by attempting a few questions on SO I can understand.

Upvotes: 2

Related Questions