0

Numpy で関数を高速化するために、ループの代わりにファンシー インデックスを使用しようとしています。私の知る限りでは、派手なインデックス作成バージョンを正しく実装しました。問題は、2 つの関数 (ループとファンシー インデックス) が同じ結果を返さないことです。理由はわかりません。より小さな配列 (たとえば、20 x 20 x 20) を使用した場合でも、関数は同じ結果を返すことに注意してください。

以下に、エラーを再現するために必要なすべてを含めました。関数が同じ結果を返す場合、行find_maxdiff(data) - find_maxdiff_fancy(data)はゼロでいっぱいの配列を返す必要があります。

from numpy import *

def rms(data, axis=0):
    return sqrt(mean(data ** 2, axis))

def find_maxdiff(data):
    samples, channels, epochs = shape(data)
    window_size = 50
    maxdiff = zeros(epochs)
    for epoch in xrange(epochs):
        signal = rms(data[:, :, epoch], axis=1)
        for t in xrange(window_size, alen(signal) - window_size):
            amp_a = mean(signal[t-window_size:t], axis=0)
            amp_b = mean(signal[t:t+window_size], axis=0)
            the_diff = abs(amp_b - amp_a)
            if the_diff > maxdiff[epoch]: 
                maxdiff[epoch] = the_diff

    return maxdiff

def find_maxdiff_fancy(data):
    samples, channels, epochs = shape(data)
    window_size = 50
    maxdiff = zeros(epochs)
    signal = rms(data, axis=1)
    for t in xrange(window_size, alen(signal) - window_size):
        amp_a = mean(signal[t-window_size:t], axis=0)
        amp_b = mean(signal[t:t+window_size], axis=0)
        the_diff = abs(amp_b - amp_a)
        maxdiff[the_diff > maxdiff] = the_diff

    return maxdiff

data = random.random((600, 20, 100))
find_maxdiff(data) - find_maxdiff_fancy(data)

data = random.random((20, 20, 20))
find_maxdiff(data) - find_maxdiff_fancy(data)
4

2 に答える 2

3

問題は次の行です。

maxdiff[the_diff > maxdiff] = the_diff

左側は maxdiff の一部の要素のみを選択しますが、右側には the_diff のすべての要素が含まれています。これは代わりに機能するはずです:

replaceElements = the_diff > maxdiff
maxdiff[replaceElements] = the_diff[replaceElements]

または単に:

maxdiff = maximum(maxdiff, the_diff)

20x20x20 サイズが機能しているように見える理由について: これは、ウィンドウのサイズが大きすぎるため、何も実行されないためです。

于 2009-11-23T13:47:47.673 に答える
0

まず、私が正しく理解すれば、あなたのシグナルは 2D になったので、明示的にインデックスを付ける方が明確になると思います (例: amp_a = mean(signal[t-window_size:t,:], axis=0)。alen も同様です。 (信号) - これはどちらの場合も単なるサンプルである必要があるため、それを使用する方が明確になると思います。

ループ内で実際に何かを実行しているときはいつでも間違っていtます - samples < window_lenght20x20x20 の例のように、そのループは決して実行されません。そのループが複数回実行されるとすぐに(つまりsamples > 2 *window_length+1)、エラーが発生します。理由はわかりませんが、彼らは私と同等に見えます.

于 2009-11-23T10:44:09.230 に答える