[英]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]:
此列表相似但不完全相同,因此我需要縮小此差距,以找到增量最低的另一個列表中第一個出現的列表。
這是我的解決方案(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.correlate
從scipy
庫:
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
在這些數據中, y1
和y2
幾乎相同(請注意添加的噪聲很小),但是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.