сравнить и рассчитать смещение между двумя массивами 1d [duplicate]

Если мы рассмотрим общие сценарии, в которых может быть выбрано это исключение, доступ к свойствам с объектом вверху.

Пример:

string postalcode=Customer.Address.PostalCode; 
//if customer or address is null , this will through exeption

здесь, если адрес имеет значение null, то вы получите NullReferenceException.

Итак, в качестве практики мы всегда должны использовать проверку нуля, прежде чем обращаться к свойствам в таких объектах (особенно в общих)

string postalcode=Customer?.Address?.PostalCode;
//if customer or address is null , this will return null, without through a exception
17
задан mtrw 14 January 2011 в 10:01
поделиться

5 ответов

scipy обеспечивает функцию корреляции, которая будет работать отлично для малого ввода, а также если вы хотите, чтобы некругловая корреляция означала, что сигнал не будет обтекать. обратите внимание, что в mode='full' размер массива, возвращаемого signal.correlation, представляет собой сумму величин входного сигнала - 1, поэтому значение из argmax отключено (размер сигнала -1 = 20) из того, что вам кажется

from scipy import signal, fftpack
import numpy
a = numpy.array([0, 1, 2, 3, 4, 3, 2, 1, 0, 1, 2, 3, 4, 3, 2, 1, 0, 0, 0, 0, 0])
b = numpy.array([0, 0, 0, 0, 0, 1, 2, 3, 4, 3, 2, 1, 0, 1, 2, 3, 4, 3, 2, 1, 0])
numpy.argmax(signal.correlate(a,b)) -> 16
numpy.argmax(signal.correlate(b,a)) -> 24

Два разных значения соответствуют тому, находится ли сдвиг в a или b.

Если вам нужна круговая корреляция и большой размер сигнала, вы можете использовать теорему преобразования свертки / Фурье с предостережением о том, что корреляция очень похожа на, но не идентична свертке.

A = fftpack.fft(a)
B = fftpack.fft(b)
Ar = -A.conjugate()
Br = -B.conjugate()
numpy.argmax(numpy.abs(fftpack.ifft(Ar*B))) -> 4
numpy.argmax(numpy.abs(fftpack.ifft(A*Br))) -> 17

снова два значения соответствуют тому, будет ли ваш перевод сдвигом в a или сдвиг в b.

Отрицательное сопряжение связано с сверткой, переворачивающей одну из функций, но в корреляции нет переворота. Вы можете отменить переворачивание либо путем изменения одного из сигналов, а затем с помощью БПФ или принятия БПФ сигнала, а затем принятия отрицательного сопряжения. то есть верно следующее: Ar = -A.conjugate() = fft(a[::-1])

30
ответ дан Gus 3 September 2018 в 17:24
поделиться

Это зависит от типа сигнала, который у вас есть (периодического? ...), о том, имеют ли оба сигнала одну и ту же амплитуду и какую точность вы ищете.

Функция корреляции, упомянутая highBandWidth, может действительно для вас. Это достаточно просто, что вы должны попробовать.

Другой, более точный вариант - это тот, который я использую для высокоточной спектральной линии: вы моделируете свой «главный» сигнал с помощью сплайна и устанавливаете сдвинутый по времени сигнал с ним (возможно, при необходимости масштабируя сигнал). Это дает очень точные сдвиги во времени. Одно из преимуществ этого подхода заключается в том, что вам не нужно изучать корреляционную функцию. Вы можете, например, легко создать сплайн с помощью interpolate.UnivariateSpline() (из SciPy). SciPy возвращает функцию, которая затем легко устанавливается с помощью optimize.leastsq ().

2
ответ дан Eric Lebigot 3 September 2018 в 17:24
поделиться

Эта функция, вероятно, более эффективна для вещественных сигналов. Он использует rfft и zero pad для входов с мощностью 2, достаточной для обеспечения линейной (т.е. некруглой) корреляции:

def rfft_xcorr(x, y):
    M = len(x) + len(y) - 1
    N = 2 ** int(np.ceil(np.log2(M)))
    X = np.fft.rfft(x, N)
    Y = np.fft.rfft(y, N)
    cxy = np.fft.irfft(X * np.conj(Y))
    cxy = np.hstack((cxy[:len(x)], cxy[N-len(y)+1:]))
    return cxy

Возвращаемое значение - длина M = len(x) + len(y) - 1 (взломанная вместе с hstack, чтобы удалить дополнительные нули от округления до степени 2). Неотрицательные лаги - cxy[0], cxy[1], ..., cxy[len(x)-1], а отрицательные лаги - cxy[-1], cxy[-2], ..., cxy[-len(y)+1].

Чтобы сопоставить опорный сигнал, я вычислил rfft_xcorr(x, ref) и искал пик. Например:

def match(x, ref):
    cxy = rfft_xcorr(x, ref)
    index = np.argmax(cxy)
    if index < len(x):
        return index
    else: # negative lag
        return index - len(cxy)   

In [1]: ref = np.array([1,2,3,4,5])
In [2]: x = np.hstack(([2,-3,9], 1.5 * ref, [0,3,8]))
In [3]: match(x, ref)
Out[3]: 3
In [4]: x = np.hstack((1.5 * ref, [0,3,8], [2,-3,-9]))
In [5]: match(x, ref)
Out[5]: 0
In [6]: x = np.hstack((1.5 * ref[1:], [0,3,8], [2,-3,-9,1]))
In [7]: match(x, ref)
Out[7]: -1

Это не надежный способ согласования сигналов, но это быстро и просто.

6
ответ дан eryksun 3 September 2018 в 17:24
поделиться

Вот еще один вариант:

from scipy import signal, fftpack

def get_max_correlation(original, match):
    z = signal.fftconvolve(original, match[::-1])
    lags = np.arange(z.size) - (match.size - 1)
    return ( lags[np.argmax(np.abs(z))] )
2
ответ дан FFT 3 September 2018 в 17:24
поделиться

Если один сдвинут во времени другим, вы увидите пик корреляции. Поскольку вычисление корреляции является дорогостоящим, лучше использовать БПФ. Итак, что-то вроде этого должно работать:

af = scipy.fft(a)
bf = scipy.fft(b)
c = scipy.ifft(af * scipy.conj(bf))

time_shift = argmax(abs(c))
9
ответ дан highBandWidth 3 September 2018 в 17:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: