

何処かの `int` 型が抜けていると思われるのですが...

**エラーメッセージ**

[code]

    Traceback (most recent call last):
      File "/Users/ymtk/Desktop/pyaudio/mfcc.py", line 109, in <module>
        mfcc = MFCC(stf.SPEC.shape[1] * 2, stf.frequency)
      File "/Users/ymtk/Desktop/pyaudio/mfcc.py", line 29, in __init__
        self.filterbank, self.fcenters = self.melFilterBank()
      File "/Users/ymtk/Desktop/pyaudio/mfcc.py", line 62, in melFilterBank
        filterbank[c, i] = (i - indexstart[c]) * increment
    IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices
    
[/code]

**ソースコード**

[code]

    #!/usr/bin/env python
    # coding=utf-8
    
    import numpy
    import scipy.fftpack
    import scipy.interpolate
    import scipy.linalg
    import sys
    
    from stf import STF
    
    class MFCC:
        '''
        MFCC computation from spectrum information
    
        Reference
        ---------
         - http://aidiary.hatenablog.com/entry/20120225/1330179868
        '''
    
        def __init__(self, nfft, frequency, dimension = 16, channels = 20):
            self.nfft = nfft
            self.frequency = frequency
            self.dimension = dimension
            self.channels = channels
    
            self.fscale = \
                numpy.fft.fftfreq(self.nfft, d = 1.0 / self.frequency)[: self.nfft / 2]
            self.filterbank, self.fcenters = self.melFilterBank()
    
        def hz2mel(self, f):
            return 1127.01048 * numpy.log(f / 700.0 + 1.0)
    
        def mel2hz(self, m):
            return 700.0 * (numpy.exp(m / 1127.01048) - 1.0)
    
        def melFilterBank(self):
            # サンプリング周波数の半分(ナイキスト周波数)までを対象とする
            fmax = self.frequency / 2
            melmax = self.hz2mel(fmax)
    
            # 周波数に合わせて、サンプル数の半分の標本数で計算する
            nmax = self.nfft / 2
            df = self.frequency / self.nfft
    
            # フィルタごとの中心となるメル尺度を計算する
            dmel = melmax / (self.channels + 1)
            melcenters = numpy.arange(1, self.channels + 1) * dmel
            fcenters = self.mel2hz(melcenters)
    
            # それぞれの標本が対象とする周波数の範囲を計算する
            indexcenter = numpy.round(fcenters / df)
            indexstart = numpy.hstack(([0], indexcenter[0: self.channels - 1]))
            indexstop = numpy.hstack((indexcenter[1: self.channels], [nmax]))
    
            # フィルタごとにindexstartを始点、indexcenterを頂点、
            # indexstopを終点とする三角形のグラフを描くように計算する
            filterbank = numpy.zeros((self.channels, nmax))
            for c in numpy.arange(0, self.channels):
                increment = 1.0 / (indexcenter[c] - indexstart[c])
                for i in numpy.arange(indexstart[c], indexcenter[c]):
                    filterbank[c, i] = (i - indexstart[c]) * increment
                decrement = 1.0 / (indexstop[c] - indexcenter[c])
                for i in numpy.arange(indexcenter[c], indexstop[c]):
                    filterbank[c, i] = 1.0 - ((i - indexcenter[c]) * decrement)
                filterbank[c] /= (indexstop[c] - indexstart[c]) / 2
    
            return filterbank, fcenters
    
        def mfcc(self, spectrum):
            # スペクトル包絡として負の値が与えられた場合は、0として扱う
            spectrum = numpy.maximum(numpy.zeros(spectrum.shape), spectrum)
            # スペクトル包絡とメルフィルタバンクの積の対数を取る
            mspectrum = numpy.log10(numpy.dot(spectrum, self.filterbank.transpose()))
            # scipyを用いて離散コサイン変換をする
            return scipy.fftpack.dct(mspectrum, norm='ortho')[:self.dimension]
    
        def delta(self, mfcc):
            # データの開始部と終了部は同じデータが続いているものとする
            mfcc = numpy.concatenate([[mfcc[0]], mfcc, [mfcc[-1]]])
    
            delta = None
            for i in xrange(1, mfcc.shape[0] - 1):
                # 前後のフレームの差を2で割ったものを動的変化量とする
                slope = (mfcc[i + 1] - mfcc[i - 1]) / 2
                if delta is None:
                    delta = slope
                else:
                    delta = numpy.vstack([delta, slope])
    
            return delta
    
        def imfcc(self, mfcc):
            # MFCCの削られた部分に0を代入した上で、逆離散コサイン変換をする
            mfcc = numpy.hstack([mfcc, [0] * (self.channels - self.dimension)])
            mspectrum = scipy.fftpack.idct(mfcc, norm='ortho')
            # 得られた離散的な値をスプライン補間によって連続的にする
            tck = scipy.interpolate.splrep(self.fcenters, numpy.power(10, mspectrum))
            return scipy.interpolate.splev(self.fscale, tck)
    
    if __name__ == '__main__':
        if len(sys.argv) < 2:
            print 'Usage: %s <ymtkyo.stf>' % sys.argv[0]
            # sys.exit()
    
        stf = STF()
        stf.loadfile("/Users/ymtk/Desktop/pyaudio/ymtkyo.stf")
    
        mfcc = MFCC(stf.SPEC.shape[1] * 2, stf.frequency)
        res = mfcc.mfcc(stf.SPEC[stf.SPEC.shape[0] / 5])
        spec = mfcc.imfcc(res)
    
        print res
    
        import pylab
    
        pylab.subplot(211)
        pylab.plot(stf.SPEC[stf.SPEC.shape[0] / 5])
        pylab.ylim(0, 1.2)
        pylab.subplot(212)
        pylab.plot(spec)
        pylab.ylim(0, 1.2)
        pylab.show()
    
[/code]


CC BY-SA 4.0
2020-01-07T11:21:40.340
62041
2021-12-19T01:00:25.023
2020-08-31T16:44:24.150
3060
37354
question
python python2
IndexError の解消法


`indexcenter` が `float64` 型になっている事が原因です。

`indexstart`, `indexstop` と同様に `int64` 型に変換しておくと良いかと。

[code]

    indexcenter = numpy.round(fcenters / df).astype(numpy.int64)
    
[/code]

* * *

_この投稿は[@metropolis
さんのコメント](https://ja.stackoverflow.com/questions/62041/indexerror-%e3%81%ae%e8%a7%a3%e6%b6%88%e6%b3%95#comment67679_62041)
の内容を元に コミュニティwiki として投稿しました。_


CC BY-SA 4.0
2020-08-31T16:48:19.737
70023
2020-08-31T16:48:19.737
3060
62041
answer