TypeError: индексы срезов должны быть целыми или None или иметь метод __index__ для временных рядов с плавающей точкой - PullRequest
0 голосов
/ 30 августа 2018

Я работаю с некоторыми файлами NetCDF. Чтобы создавать удобочитаемые графики, я хочу сгладить ежедневные данные за длительные периоды времени. Я сделал эту маленькую функцию для этого:

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

к сожалению, когда я использую эту функцию в одном из моих переменных временных рядов, как показано в следующем коде:

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)

Я получил следующее сообщение об ошибке:

    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

Да, очевидно, мои данные не являются целыми числами ... Кто-нибудь знает, как преодолеть эту ошибку?

1 Ответ

0 голосов
/ 30 августа 2018

Думаю, я понял это. Я еще не тестировал его для Python 2, но Думаю, я знаю, почему он не работает в Python 3.

В вашем первом блоке кода, определяющем функцию mov_avg, ваши первые два аргумента - x и window. В функции у вас есть строка:

wd1=(window-1)/2

Когда вы вызываете функцию, вы вызываете ее как:

obs_smooth = mov_avg(obs,7)

, где window=7. В теле функции вычисляется wd1, но оно не оценивается как 3, оно оценивается как 3,0 - значение с плавающей запятой, а не целое число. Поэтому, когда он пытается выполнить строку, начинающуюся с yyF[:,wd1:-wd1], происходит сбой, поскольку wd1 не является целым числом.

Вы можете попробовать использовать функцию int() для преобразования ее в число с плавающей точкой.

Я протестировал доступ к образцу списка с использованием значений с плавающей запятой и целых чисел на установке по умолчанию Python 3.6.5, установленной с использованием 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

А в конкретном случае ваш код:

>>> 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: в Python 2 результатом последней операции будет целое число, а не число с плавающей точкой. Возможно, именно поэтому он работает на Python 2, а не на Python 3?

Отказ от ответственности : Я новичок в программировании, поэтому, если это не причина, извините! Я пытаюсь узнать больше, пытаясь ответить на несколько вопросов, чтобы я мог понять.

...