簡體   English   中英

查找numpy數組之間的最小差異的位置

[英]Find the position of a lowest difference between numpy arrays

我有兩個音樂文件:一個是無損且音隙很小(此時只是沉默,但可能是任何東西:正弦波或只是一些噪音),一首mp3:

In [1]: plt.plot(y[:100000])
Out[1]: 

無損文件

In [2]: plt.plot(y2[:100000])
Out[2]: 

mp3文件

此列表相似但不完全相同,因此我需要縮小此差距,以找到增量最低的另一個列表中第一個出現的列表。

這是我的解決方案(5.7065秒):

error = []
for i in range(25000):
    y_n = y[i:100000]
    y2_n = y2[:100000-i]
    error.append(abs(y_n - y2_n).mean())
start = np.array(error).argmin()

print(start, error[start]) #23057 0.0100046

有什么pythonic方法可以解決這個問題嗎?

編輯:計算出特殊點之間的平均距離(例如,數據== 0.5)后,我將搜索范圍從25000減少到2000。這給了我0.3871s的合理時間:

a = np.where(y[:100000].round(1) == 0.5)[0]
b = np.where(y2[:100000].round(1) == 0.5)[0]

mean = int((a - b[:len(a)]).mean())
delta = 1000

error = []
for i in range(mean - delta, mean + delta):
...

您正在嘗試做的是兩個信號的互相關

這可以很容易用做signal.correlatescipy庫:

import scipy.signal
import numpy as np

# limit your signal length to speed things up
lim = 25000

# do the actual correlation
corr = scipy.signal.correlate(y[:lim], y2[:lim], mode='full')

# The offset is the maximum of your correlation array,
# itself being offset by (lim - 1):
offset = np.argmax(corr) - (lim - 1)

您可能想看看這個類似問題的答案。

讓我們先生成一些數據

N = 1000
y1 = np.random.randn(N)
y2 = y1 + np.random.randn(N) * 0.05
y2[0:int(N / 10)] = 0

在這些數據中, y1y2 幾乎相同(請注意添加的噪聲很小),但是y2的前10%為空(類似於您的示例)

現在我們可以計算兩個向量之間的絕對差,並找到絕對差低於靈敏度閾值的第一個元素:

abs_delta = np.abs(y1 - y2)
THRESHOLD = 1e-2
sel = abs_delta < THRESHOLD
ix_start = np.where(sel)[0][0]


fig, axes = plt.subplots(3, 1)
ax = axes[0]
ax.plot(y1, '-')
ax.set_title('y1')
ax.axvline(ix_start, color='red')
ax = axes[1]
ax.plot(y2, '-')
ax.axvline(ix_start, color='red')
ax.set_title('y2')

ax = axes[2]
ax.plot(abs_delta)
ax.axvline(ix_start, color='red')
ax.set_title('abs diff')

繪制樣本數據

如果重疊部分確實“幾乎相同”,則此方法有效。 如果相似性很低,您將不得不考慮更智能的對齊方式。

我認為您正在尋找的是相關性。 這是一個小例子。

import numpy as np

equal_part = [0, 1, 2, 3, -2, -4, 5, 0]
y1 = equal_part + [0, 1, 2, 3, -2, -4, 5, 0]
y2 = [1, 2, 4, -3, -2, -1, 3, 2]+y1

np.argmax(np.correlate(y1, y2, 'same'))

出:

7

因此,這將返回時差,其中兩個信號之間的相關性最大。 如您所見,在該示例中,時間差應為8,但這取決於您的數據...另外請注意,兩個信號的長度相同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM