4

現在、python と numpy/scipy を使用してビート検出アルゴリズムを実装しています。基本的に、.wav ファイルを読み取って処理する必要があります。コードは次のとおりです。

sampling_rate, wave_data = scipy.io.wavfile.read(argv[1])

wave_dataは、約 441,000 要素 (44.1 kHz のサンプリング レートで 10 秒間のサウンド) を持つ 1 次元の numpy 配列です。ここで、この配列の 2 つの要素ごとに基本的な計算を行う必要があります。これは私が今それを行う方法です:

wave_data = [sampling_rate * (wave_data[i+1] - wave_data[i]) 
             for i in xrange(len(wave_data)-1)]

この操作には時間がかかりすぎます (プロファイリングをしなくてもわかります)。新しいpythonリストを作成せずに、配列をペアごとに「インプレース」でマップする必要があります。があることは知ってnumpy.vectorizeいますが、ペアごとにマッピングを行う方法がわかりません(配列の2つの要素ごとにマッピングします)。

4

1 に答える 1

4

次のいずれかがそれを行います。

wave_date = sampling_rate * np.diff(wave_data)

また

wave_date = sampling_rate * (wave_data[1:] - wave_data[:-1])

例えば:

In [7]: sampling_rate = 2

In [8]: wave_data = np.array([1, 3, 5, 2, 8, 10])

In [9]: sampling_rate * (wave_data[1:] - wave_data[:-1])
Out[9]: array([ 4,  4, -6, 12,  4])

パフォーマンスに関する限り、これらのアプローチはどちらもリスト内包表記よりも約 500 倍高速です。

In [16]: wave_data = np.array([1., 3, 5, 2, 8, 10, 5, 2, 4, 7] * 44100)

In [17]: %timeit sampling_rate * np.diff(wave_data)
100 loops, best of 3: 2.2 ms per loop

In [18]: %timeit sampling_rate * (wave_data[1:] - wave_data[:-1])
100 loops, best of 3: 2.15 ms per loop

In [19]: %timeit [sampling_rate * (wave_data[i+1] - wave_data[i]) for i in xrange(len(wave_data)-1)]
1 loops, best of 3: 970 ms per loop
于 2013-02-03T13:05:02.883 に答える