Python Tìm đỉnh và thung lũng

Cho một Danh sách, bài viết sau đây chỉ ra các cách đếm các phần tử là đỉnh[x > y < z] hoặc đáy [x < y > z]

Đầu vào. test_list = [1, 2, 4, 2, 6, 7, 8, 3]
đầu ra. 3
Giải trình. [2, 4, 2], [4, 2, 6], [7, 8, 3] là đỉnh và đáy.  
Đầu vào. test_list = [1, 2, 4, 5, 3, 2]
đầu ra. 1
Giải trình. [4, 5, 3] là đỉnh.  

Phương pháp 1. Sử dụng vòng lặp

Trong phần này, chúng tôi lặp lại từng phần tử và kiểm tra xem phần tử tiếp theo và trước đó của nó nhỏ hơn hay lớn hơn phần tử hiện tại. Nếu tìm thấy, bộ đếm được tăng lên

Python3




# initializing list

test_list= [1,2,4,2,test_list2,test_list4,test_list6,test_list8test_list9

=0

=1

=2=3=4 =5 =6=7

=0

=9= [1

[2 [3[4 [5_______68_______31,[91011 113

1415 16=5 1___1911 1test_list9,3 16=5 1,711 120

21=9=5= 1

=0

27

=2=3,0 =5 =6,3

đầu ra

Danh sách ban đầu là. [1, 2, 4, 2, 6, 7, 8, 3]

Số lượng đỉnh và thung lũng. 3

Phương pháp 2. Sử dụng hiểu danh sách và len[]

Trong phần này, chúng tôi thực hiện nhiệm vụ lấy đỉnh và đáy bằng cách sử dụng khả năng hiểu danh sách và sau đó len[] được sử dụng để tính toán số lượng chính xác

Python3




# initializing list

test_list= [1,2,4,2,test_list2,test_list4,test_list6,test_list8test_list9

=0

=1

=2=3=4 =5 =6=7

=0

test_list03

=9= [9test_list07[2 [3[4 [5=31,[91011 1test_list1915 16_______68_______5 1________47

test_list25test_list2611 1test_list9,3 16=5 1,711 1test_list37

Trong nhiều ứng dụng xử lý tín hiệu, việc tìm các đỉnh là một phần quan trọng của đường ống. Phát hiện đỉnh có thể là một nỗ lực rất khó khăn, thậm chí còn khó hơn khi có nhiều tiếng ồn. Trong bài đăng này, tôi đang nghiên cứu các cách khác nhau để tìm các đỉnh trong tín hiệu nhiễu. Chúng tôi khám phá các hàm

sos = scipy.signal.iirfilter[4, Wn=[0.1, 2.5], fs=fs, btype="bandpass",
                             ftype="butter", output="sos"]
yfilt = scipy.signal.sosfilt[sos, yraw]
2 và
sos = scipy.signal.iirfilter[4, Wn=[0.1, 2.5], fs=fs, btype="bandpass",
                             ftype="butter", output="sos"]
yfilt = scipy.signal.sosfilt[sos, yraw]
3 cực kỳ hữu ích của SciPy và phát triển một phương pháp tìm đỉnh thô sơ từ đầu trong JavaScript. Việc triển khai JavaScript được sử dụng để điều khiển một phần mô tả của siêu đường kính
sos = scipy.signal.iirfilter[4, Wn=[0.1, 2.5], fs=fs, btype="bandpass",
                             ftype="butter", output="sos"]
yfilt = scipy.signal.sosfilt[sos, yraw]
2

Phát hiện đỉnh trong Python bằng SciPy

Để tìm các đỉnh trong mảng 1 chiều, mô-đun xử lý tín hiệu SciPy cung cấp chức năng

sos = scipy.signal.iirfilter[4, Wn=[0.1, 2.5], fs=fs, btype="bandpass",
                             ftype="butter", output="sos"]
yfilt = scipy.signal.sosfilt[sos, yraw]
7 mạnh mẽ. Việc sử dụng hàm khá đơn giản, phần khó hơn là tìm các đối số phù hợp cho trường hợp sử dụng cụ thể của bạn. Có một số tùy chọn khác nhau ảnh hưởng đến số lượng và số lượng đỉnh được phát hiện. Tài liệu SciPy có một số ghi chú chi tiết về các thông số này

Định nghĩa của các đỉnh

Trước khi tìm hiểu các đối số của hàm, chúng ta cần trả lời một câu hỏi cơ bản hơn. một đỉnh là gì? . Một mẫu $y[k]$ được coi là đỉnh, nếu giá trị lớn hơn hai giá trị lân cận trực tiếp của nó [cực đại cục bộ]. $$ y[k] > y[k-1]\text{ và } y[k] > y[k+1] $$ Về mặt trực quan, rõ ràng là tiêu chí cơ bản này có thể không đủ đối với tín hiệu nhiễu. Dưới đây là tín hiệu ví dụ với tất cả các cực đại cục bộ được tô sáng cho sóng hình sin phủ nhiễu Gaussian. Rõ ràng, cần áp đặt nhiều ràng buộc hơn để chỉ tìm các đỉnh có liên quan

Loại bỏ các đỉnh không mong muốn với các thuộc tính cần thiết

Để lọc danh sách ban đầu của cực đại cục bộ, chúng ta có thể xác định tiêu chí bổ sung. Ví dụ: trong

sos = scipy.signal.iirfilter[4, Wn=[0.1, 2.5], fs=fs, btype="bandpass",
                             ftype="butter", output="sos"]
yfilt = scipy.signal.sosfilt[sos, yraw]
2, chúng tôi có thể chỉ định khoảng cách tối thiểu giữa các đỉnh, chiều cao tối thiểu và một số thuộc tính phức tạp hơn. Việc sử dụng tiêu chí nào và chọn giá trị ngưỡng nào phụ thuộc nhiều vào trường hợp sử dụng cụ thể. Thông thường, bạn cần đưa ra một số giả định về các tín hiệu đầu vào dự kiến ​​để chọn các tham số hữu ích

Hãy thử với hai trong số các tham số này để giảm danh sách các đỉnh được phát hiện. Chúng tôi đang mô phỏng giây tín hiệu nhiễu dao động với tần số Hz [được ghi ở 30 mẫu mỗi giây]. Sử dụng các thanh trượt bên dưới để điều tra tác động của việc thay đổi các giá trị tương ứng. Nhấp vào “Làm mới dữ liệu” để tạo tín hiệu ngẫu nhiên mới và kiểm tra cài đặt của bạn trên dữ liệu mới. Bạn có thể tìm thấy một cài đặt hoạt động mọi lúc không?

Chiều cao tối thiểu 0. 5

Khoảng cách tối thiểu 0. 5

 

Tùy thuộc vào tần số của tín hiệu, các cài đặt khác nhau cho khoảng cách tối thiểu có thể có các hiệu ứng cực kỳ khác nhau. Đối với tín hiệu có tần số $f$, bạn sẽ chọn khoảng cách tối thiểu ở đâu đó giữa $\tfrac{1}{2f}$ và $\tfrac{1}{f}$. Nhưng phải luôn có một số khoảng trống cho những sai lệch nhỏ hơn so với hành vi dự kiến. Với chiều cao tối thiểu, chúng tôi có thể đảm bảo rằng các đỉnh dưới một ngưỡng nhất định thậm chí không được coi là ứng cử viên. Các giá trị gần bằng 0 [50% biên độ từ đỉnh đến đỉnh] là một lựa chọn tốt trong ví dụ trên. Đối với những người tò mò về cách triển khai JavaScript đằng sau hình ảnh trực quan này, hãy tiếp tục đọc cho đến khi

sos = scipy.signal.iirfilter[4, Wn=[0.1, 2.5], fs=fs, btype="bandpass",
                             ftype="butter", output="sos"]
yfilt = scipy.signal.sosfilt[sos, yraw]
7 cung cấp thêm một số tiêu chí để lựa chọn đỉnh, được mô tả khá rõ trong tài liệu. Ví dụ: độ rộng cực đại và độ nổi bật của cực đại không chỉ nhìn vào một mẫu duy nhất với cực đại cục bộ mà còn ở hình dạng tín hiệu xung quanh cực đại

Phát hiện đỉnh trong tín hiệu nhiễu

Một số đỉnh trong ví dụ trên hơi lệch tâm một chút. Chúng không căn chỉnh đúng với tần số tín hiệu cơ bản. Đây là một vấn đề phổ biến khi có tiếng ồn. Nếu chúng ta không quan tâm đến vị trí chính xác của các giá trị cao nhất mà quan tâm đến tâm sóng, thì chúng ta cần xử lý nhiễu. Gói SciPy cung cấp chức năng

sos = scipy.signal.iirfilter[4, Wn=[0.1, 2.5], fs=fs, btype="bandpass",
                             ftype="butter", output="sos"]
yfilt = scipy.signal.sosfilt[sos, yraw]
3, tìm kiếm các đỉnh trong một số phiên bản được làm mịn của tín hiệu gốc. Ở đây, CWT là viết tắt của biến đổi wavelet liên tục, là một công cụ xử lý tín hiệu được sử dụng trong các ứng dụng khác nhau từ nén đến phân tích tín hiệu sinh học

Ngoài ra, chúng ta có thể áp dụng rõ ràng bộ lọc thông thấp và tìm các đỉnh trong tín hiệu được làm mịn. Tôi đã chỉ ra cách các bộ lọc kỹ thuật số có thể được áp dụng trong Python trong bài viết trước của tôi. Hãy so sánh

sos = scipy.signal.iirfilter[4, Wn=[0.1, 2.5], fs=fs, btype="bandpass",
                             ftype="butter", output="sos"]
yfilt = scipy.signal.sosfilt[sos, yraw]
3 và làm mịn rõ ràng với tín hiệu tổng hợp. Đầu tiên, tôi đang tạo một tín hiệu ví dụ

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import numpy as np

np.random.seed[256]  # for reproducibility

# create time steps and corresponding sine wave with Gaussian noise
fs = 30  # sampling rate, Hz
ts = np.arange[0, 8, 1.0 / fs]  # time vector - 8 seconds

ys = np.sin[2*np.pi * 1.0 * ts]  # signal @ 1.0 Hz, without noise
yerr = 0.5 * np.random.normal[size=len[ts]]  # Gaussian noise
yraw = ys + yerr

Tiếp theo, chúng tôi xác định bộ lọc thông dải, loại bỏ nhiễu

1
2
3
sos = scipy.signal.iirfilter[4, Wn=[0.1, 2.5], fs=fs, btype="bandpass",
                             ftype="butter", output="sos"]
yfilt = scipy.signal.sosfilt[sos, yraw]

Bây giờ, chúng ta có thể áp dụng cả hai phương pháp tìm đỉnh và trực quan hóa kết quả. Đối với ví dụ này, tôi đã chọn thủ công các tham số chức năng để hoạt động hợp lý với tốc độ xung mô phỏng trong khoảng từ 50 đến 150 bpm [nhịp mỗi phút]. Đối với phương pháp thông thường [

sos = scipy.signal.iirfilter[4, Wn=[0.1, 2.5], fs=fs, btype="bandpass",
                             ftype="butter", output="sos"]
yfilt = scipy.signal.sosfilt[sos, yraw]
2] được áp dụng cho tín hiệu được làm mịn, khoảng cách tối thiểu cho phép được đặt thành 0. 35 giây, tương ứng với tần số xung tối đa khoảng 170 bpm. Bằng cách đặt thêm chiều cao cực đại tối thiểu thành 0, các đỉnh ngẫu nhiên nhỏ hơn [như đỉnh ở khoảng 0. 8 giây trong hình bên dưới] bị bỏ quên

Đối với phương pháp dựa trên wavelet [_______0_______3], chúng ta có thể chỉ định tham số

1
2
3
4
4. Độ rộng được cung cấp tương ứng với các mức độ làm mịn khác nhau [độ rộng wavelet]. Theo tài liệu,
1
2
3
4
4 nên bao gồm chiều rộng đỉnh dự kiến. Đối với các tần số tín hiệu khác nhau, tôi thấy
1
2
3
4
6 hoạt động tốt. Chiều rộng tối thiểu 5 mẫu tương ứng với 0. 167 giây, gần bằng một nửa thời gian chu kỳ với tần số 170 bpm. Ở đầu kia, chiều rộng 15 mẫu tương ứng với chiều rộng cực đại là 0. 5 giây. Chọn độ rộng lớn hơn cho tín hiệu ví dụ này dẫn đến thuật toán thiếu một số đỉnh

1
2
3
4
# find peaks in smoothed signal
peaks, props = scipy.signal.find_peaks[yfilt, distance=0.35*fs, height=0.0]
# find peaks in noisy signal using wavelet decomposition
cwt_peaks = scipy.signal.find_peaks_cwt[yraw, widths=np.arange[5, 15]]

Cả hai phương pháp đều hoạt động khá tốt và kết quả đầu ra tương ứng gần như giống hệt nhau

Chi phí tính toán của
sos = scipy.signal.iirfilter[4, Wn=[0.1, 2.5], fs=fs, btype="bandpass",
                             ftype="butter", output="sos"]
yfilt = scipy.signal.sosfilt[sos, yraw]
2 và
sos = scipy.signal.iirfilter[4, Wn=[0.1, 2.5], fs=fs, btype="bandpass",
                             ftype="butter", output="sos"]
yfilt = scipy.signal.sosfilt[sos, yraw]
3

Khi lựa chọn giữa hai, một yếu tố quan trọng cần xem xét là nỗ lực tính toán. Chúng ta có thể so sánh hai cách tiếp cận bằng cách sử dụng. Đối với tín hiệu 8 giây từ trước đó, sử dụng

sos = scipy.signal.iirfilter[4, Wn=[0.1, 2.5], fs=fs, btype="bandpass",
                             ftype="butter", output="sos"]
yfilt = scipy.signal.sosfilt[sos, yraw]
2 với khả năng làm mịn rõ ràng sẽ nhanh hơn khoảng 4 lần´ [ngay cả khi bao gồm cả thiết kế bộ lọc]. Đối với các tín hiệu dài hơn, sự khác biệt càng trở nên nghiêm trọng hơn. Vì vậy, nếu tốc độ tính toán là một vấn đề đối với ứng dụng của bạn, bạn có thể thích tùy chọn đầu tiên hơn

1
2
3
4
5
6
7
%%timeit
sos = scipy.signal.iirfilter[2, Wn=[0.1, 2.5], fs=fs, btype="bandpass",
                             ftype="butter", output="sos"]
yfilt = scipy.signal.sosfiltfilt[sos, yraw]
peaks, props = scipy.signal.find_peaks[yfilt, distance=0.35*fs, height=0.0]

#> 749 µs ± 4.3 µs per loop [mean ± std. dev. of 7 runs, 1,000 loops each]

1
2
3
4
%%timeit
cwt_peaks = scipy.signal.find_peaks_cwt[yraw, widths=np.arange[5, 15]]

#> 3.47 ms ± 17.4 µs per loop [mean ± std. dev. of 7 runs, 100 loops each]

Triển khai bộ lọc đỉnh trong JavaScript

Đối với những điều trên, tôi đã phải triển khai một số phần của phương thức

sos = scipy.signal.iirfilter[4, Wn=[0.1, 2.5], fs=fs, btype="bandpass",
                             ftype="butter", output="sos"]
yfilt = scipy.signal.sosfilt[sos, yraw]
2 trong JavaScript. Thật ấn tượng khi thấy có bao nhiêu mã được gói gọn trong một dòng từ thư viện SciPy — và tôi thậm chí còn không triển khai tất cả các tính năng của
sos = scipy.signal.iirfilter[4, Wn=[0.1, 2.5], fs=fs, btype="bandpass",
                             ftype="butter", output="sos"]
yfilt = scipy.signal.sosfilt[sos, yraw]
2

Tìm cực đại cục bộ và lọc theo chiều cao

Bước đầu tiên của phương pháp

sos = scipy.signal.iirfilter[4, Wn=[0.1, 2.5], fs=fs, btype="bandpass",
                             ftype="butter", output="sos"]
yfilt = scipy.signal.sosfilt[sos, yraw]
2 khá đơn giản. chúng ta cần tìm tất cả các cực đại cục bộ. Điều này đạt được bằng cách lặp qua tín hiệu đầu vào và lưu ý tất cả các chỉ số trong đó giá trị tín hiệu cao hơn cả hai tín hiệu lân cận ngay lập tức

import numpy as np

np.random.seed[256]  # for reproducibility

# create time steps and corresponding sine wave with Gaussian noise
fs = 30  # sampling rate, Hz
ts = np.arange[0, 8, 1.0 / fs]  # time vector - 8 seconds

ys = np.sin[2*np.pi * 1.0 * ts]  # signal @ 1.0 Hz, without noise
yerr = 0.5 * np.random.normal[size=len[ts]]  # Gaussian noise
yraw = ys + yerr
0_______9_______1

Tiếp theo, chúng ta có thể lọc cực đại cục bộ theo chiều cao cực đại tối thiểu và khoảng cách cực đại tối thiểu. SciPy rõ ràng về thứ tự của các hoạt động này. Các hoạt động tính toán ít chuyên sâu hơn được thực hiện trước, do đó các bộ lọc phức tạp hơn cần xử lý ít chỉ số hơn. Việc lọc theo chiều cao cực đại có thể được thực hiện trong một dòng trong JavaScript, nhưng dù sao thì việc xác định một hàm sẽ rõ ràng hơn

import numpy as np

np.random.seed[256]  # for reproducibility

# create time steps and corresponding sine wave with Gaussian noise
fs = 30  # sampling rate, Hz
ts = np.arange[0, 8, 1.0 / fs]  # time vector - 8 seconds

ys = np.sin[2*np.pi * 1.0 * ts]  # signal @ 1.0 Hz, without noise
yerr = 0.5 * np.random.normal[size=len[ts]]  # Gaussian noise
yraw = ys + yerr
2
import numpy as np

np.random.seed[256]  # for reproducibility

# create time steps and corresponding sine wave with Gaussian noise
fs = 30  # sampling rate, Hz
ts = np.arange[0, 8, 1.0 / fs]  # time vector - 8 seconds

ys = np.sin[2*np.pi * 1.0 * ts]  # signal @ 1.0 Hz, without noise
yerr = 0.5 * np.random.normal[size=len[ts]]  # Gaussian noise
yraw = ys + yerr
3

Ở đây, tôi đang sử dụng

# find peaks in smoothed signal
peaks, props = scipy.signal.find_peaks[yfilt, distance=0.35*fs, height=0.0]
# find peaks in noisy signal using wavelet decomposition
cwt_peaks = scipy.signal.find_peaks_cwt[yraw, widths=np.arange[5, 15]]
4 tích hợp kết hợp với chức năng mũi tên. Bạn có thể tìm thêm thông tin chi tiết về
# find peaks in smoothed signal
peaks, props = scipy.signal.find_peaks[yfilt, distance=0.35*fs, height=0.0]
# find peaks in noisy signal using wavelet decomposition
cwt_peaks = scipy.signal.find_peaks_cwt[yraw, widths=np.arange[5, 15]]
5 và các hàm mũi tên tại đây

Lọc cực đại cục bộ theo khoảng cách cực đại tối thiểu

Loại bỏ các đỉnh quá gần với các đỉnh lớn hơn sẽ phức tạp hơn một chút và không thể đạt được trong một dòng. Tôi đã phải tìm hiểu mã SciPy để hiểu đúng và chỉ điều chỉnh mã một chút. Ý tưởng chính của mã bên dưới là duyệt qua danh sách các đỉnh từ cao nhất đến nhỏ nhất, xác định tất cả các đỉnh nhỏ hơn ở ngay xung quanh đỉnh hiện tại [được xác định bằng khoảng cách tối thiểu] và đánh dấu chúng để loại bỏ

Để điều này hoạt động, chúng ta cần có khả năng truy cập mảng chỉ số đỉnh từ góc nhìn thứ hai. với chiều cao giảm dần. Trong Python, tôi sẽ sử dụng hàm

# find peaks in smoothed signal
peaks, props = scipy.signal.find_peaks[yfilt, distance=0.35*fs, height=0.0]
# find peaks in noisy signal using wavelet decomposition
cwt_peaks = scipy.signal.find_peaks_cwt[yraw, widths=np.arange[5, 15]]
6 để lấy thứ tự truy cập các đỉnh. Rất may, tôi đã tìm thấy triển khai JavaScript 3 dòng trên StackOverflow

1
2
3
4
import numpy as np

np.random.seed[256]  # for reproducibility

# create time steps and corresponding sine wave with Gaussian noise
fs = 30  # sampling rate, Hz
ts = np.arange[0, 8, 1.0 / fs]  # time vector - 8 seconds

ys = np.sin[2*np.pi * 1.0 * ts]  # signal @ 1.0 Hz, without noise
yerr = 0.5 * np.random.normal[size=len[ts]]  # Gaussian noise
yraw = ys + yerr
5

Đưa ra một danh sách các giá trị,

# find peaks in smoothed signal
peaks, props = scipy.signal.find_peaks[yfilt, distance=0.35*fs, height=0.0]
# find peaks in noisy signal using wavelet decomposition
cwt_peaks = scipy.signal.find_peaks_cwt[yraw, widths=np.arange[5, 15]]
7 trả về một mảng với các chỉ số cho biết cách chúng ta sẽ truy cập danh sách theo thứ tự tăng dần. Đây là một ví dụ

import numpy as np

np.random.seed[256]  # for reproducibility

# create time steps and corresponding sine wave with Gaussian noise
fs = 30  # sampling rate, Hz
ts = np.arange[0, 8, 1.0 / fs]  # time vector - 8 seconds

ys = np.sin[2*np.pi * 1.0 * ts]  # signal @ 1.0 Hz, without noise
yerr = 0.5 * np.random.normal[size=len[ts]]  # Gaussian noise
yraw = ys + yerr
6
import numpy as np

np.random.seed[256]  # for reproducibility

# create time steps and corresponding sine wave with Gaussian noise
fs = 30  # sampling rate, Hz
ts = np.arange[0, 8, 1.0 / fs]  # time vector - 8 seconds

ys = np.sin[2*np.pi * 1.0 * ts]  # signal @ 1.0 Hz, without noise
yerr = 0.5 * np.random.normal[size=len[ts]]  # Gaussian noise
yraw = ys + yerr
7

# find peaks in smoothed signal
peaks, props = scipy.signal.find_peaks[yfilt, distance=0.35*fs, height=0.0]
# find peaks in noisy signal using wavelet decomposition
cwt_peaks = scipy.signal.find_peaks_cwt[yraw, widths=np.arange[5, 15]]
7 cho chúng ta biết rằng chúng ta có thể tìm thấy giá trị nhỏ nhất [10] ở vị trí 2 của mảng đầu vào [không có chỉ mục], giá trị lớn hơn tiếp theo [20] ở chỉ mục 4, v.v.

Được trang bị công cụ này, cuối cùng chúng ta có thể lọc danh sách các đỉnh theo khoảng cách tối thiểu. Đây là chức năng đầy đủ, nhưng tôi sẽ chia nhỏ nó bên dưới

import numpy as np

np.random.seed[256]  # for reproducibility

# create time steps and corresponding sine wave with Gaussian noise
fs = 30  # sampling rate, Hz
ts = np.arange[0, 8, 1.0 / fs]  # time vector - 8 seconds

ys = np.sin[2*np.pi * 1.0 * ts]  # signal @ 1.0 Hz, without noise
yerr = 0.5 * np.random.normal[size=len[ts]]  # Gaussian noise
yraw = ys + yerr
8
import numpy as np

np.random.seed[256]  # for reproducibility

# create time steps and corresponding sine wave with Gaussian noise
fs = 30  # sampling rate, Hz
ts = np.arange[0, 8, 1.0 / fs]  # time vector - 8 seconds

ys = np.sin[2*np.pi * 1.0 * ts]  # signal @ 1.0 Hz, without noise
yerr = 0.5 * np.random.normal[size=len[ts]]  # Gaussian noise
yraw = ys + yerr
9

Trước khi lặp qua các đỉnh, chúng ta cần xác định một số mảng phụ trợ. Với

# find peaks in smoothed signal
peaks, props = scipy.signal.find_peaks[yfilt, distance=0.35*fs, height=0.0]
# find peaks in noisy signal using wavelet decomposition
cwt_peaks = scipy.signal.find_peaks_cwt[yraw, widths=np.arange[5, 15]]
9, chúng tôi có thể lưu ý tất cả các đỉnh quá gần với các đỉnh lớn hơn và do đó có thể bị xóa.
1
2
3
4
5
6
7
0 cung cấp cho chúng tôi các chiều cao cực đại mà chúng tôi có thể sử dụng để lấy thứ tự truy cập cho phép lặp mảng [được lưu trữ trong
1
2
3
4
5
6
7
1]. Lưu ý rằng đầu ra
# find peaks in smoothed signal
peaks, props = scipy.signal.find_peaks[yfilt, distance=0.35*fs, height=0.0]
# find peaks in noisy signal using wavelet decomposition
cwt_peaks = scipy.signal.find_peaks_cwt[yraw, widths=np.arange[5, 15]]
7 bị đảo ngược, để chúng ta có thể đi từ cao nhất đến thấp nhất

1
2
3
0
1
2
3
1

Bây giờ, chúng tôi lặp qua danh sách các đỉnh, bắt đầu từ đỉnh cao nhất, được gọi là

1
2
3
4
5
6
7
3 bên dưới. Nếu đỉnh hiện tại đã được đánh dấu để loại bỏ, nó có thể được bỏ qua

1
2
3
2_______10_______3

Từ đỉnh hiện tại, trước tiên chúng tôi nhìn về phía bên trái, nhảy từ đỉnh này sang đỉnh khác và đánh dấu chúng để loại bỏ. Chúng tôi đi sang trái cho đến khi khoảng cách từ đỉnh hiện tại lớn hơn khoảng cách đỉnh tối thiểu do người dùng chỉ định

1
2
3
4
5
6
7
4 hoặc chúng tôi đến điểm bắt đầu của tín hiệu

1
2
3
4
1
2
3
5

Bạn có thể thắc mắc, tại sao không có so sánh độ cao của đỉnh giữa đỉnh hiện tại và đỉnh lân cận. Điều này thực sự không cần thiết vì chúng tôi đã xem qua danh sách từ cao nhất đến thấp nhất. Và chúng tôi không thể xem lại đỉnh cao hơn trong khi kiểm tra các đỉnh lân cận, vì tất cả các đỉnh gần với các đỉnh được xử lý trước đó đã được đánh dấu để xóa

Phía bên phải của đỉnh được kiểm tra theo cách tương tự

1
2
3
6_______10_______7

Cuối cùng, danh sách ban đầu của các chỉ số đỉnh có thể được lọc theo các ghi chú trong

# find peaks in smoothed signal
peaks, props = scipy.signal.find_peaks[yfilt, distance=0.35*fs, height=0.0]
# find peaks in noisy signal using wavelet decomposition
cwt_peaks = scipy.signal.find_peaks_cwt[yraw, widths=np.arange[5, 15]]
9

1
2
3
8
1
2
3
9

Đặt các mảnh lại với nhau

Với các chức năng xác định cực đại cục bộ và giảm danh sách theo khoảng cách và chiều cao tối thiểu, chúng ta có thể tạo một chức năng cung cấp ít nhất một phần chức năng

sos = scipy.signal.iirfilter[4, Wn=[0.1, 2.5], fs=fs, btype="bandpass",
                             ftype="butter", output="sos"]
yfilt = scipy.signal.sosfilt[sos, yraw]
2 của SciPy. Đây là những gì tôi đã sử dụng để thúc đẩy hình ảnh tương tác ở trên

sos = scipy.signal.iirfilter[4, Wn=[0.1, 2.5], fs=fs, btype="bandpass",
                             ftype="butter", output="sos"]
yfilt = scipy.signal.sosfilt[sos, yraw]
0
sos = scipy.signal.iirfilter[4, Wn=[0.1, 2.5], fs=fs, btype="bandpass",
                             ftype="butter", output="sos"]
yfilt = scipy.signal.sosfilt[sos, yraw]
1

Phần kết luận

Nhiễu là một thách thức luôn hiện hữu trong xử lý tín hiệu. Nếu chúng tôi muốn tìm các đỉnh trong tín hiệu nhiễu, chúng tôi có một số tùy chọn, có sẵn trong hệ sinh thái Python.

sos = scipy.signal.iirfilter[4, Wn=[0.1, 2.5], fs=fs, btype="bandpass",
                             ftype="butter", output="sos"]
yfilt = scipy.signal.sosfilt[sos, yraw]
2 tìm tất cả các cực đại cục bộ trong tín hiệu và rút gọn danh sách dựa trên tiêu chí do người dùng chỉ định

Chúng tôi đã khám phá ảnh hưởng của tiêu chí chiều cao cực đại tối thiểu và khoảng cách cực đại tối thiểu, có thể dẫn đến kết quả tốt. Để xử lý nhiễu, trước tiên có thể làm mịn đầu vào trước khi áp dụng phát hiện đỉnh. Thay vào đó, SciPy cung cấp cách tiếp cận dựa trên biến đổi wavelet find_peaks_cwt được xác định cụ thể để tìm các đỉnh trong tín hiệu nhiễu. Bất kể cách tiếp cận nào, luôn cần phải đưa ra các giả định về hình dạng tín hiệu dự kiến, để thiết lập các siêu tham số có ý nghĩa

Cuối cùng, tôi đã chỉ ra cách các phần của hàm

sos = scipy.signal.iirfilter[4, Wn=[0.1, 2.5], fs=fs, btype="bandpass",
                             ftype="butter", output="sos"]
yfilt = scipy.signal.sosfilt[sos, yraw]
2 hoạt động và triển khai lại các phần đó trong JavaScript. Thật ngạc nhiên là có bao nhiêu chức năng được cung cấp trong SciPy, nó cũng dễ sử dụng và được ghi lại rất đầy đủ. Kudo cho những người bảo trì để làm cho điều này có sẵn

Nếu bạn muốn xây dựng trên bài đăng này, bạn có thể tải xuống mã Python và JavaScript từ GitHub của tôi hoặc

[Người giới thiệu]

  1. P. Du, W. Một. Kibbe và S. m. Lin, “Đã cải thiện khả năng phát hiện cực đại trong phổ khối bằng cách kết hợp khớp mẫu dựa trên biến đổi wavelet liên tục,” Bioinformatics, tập. 22, không. 17, trang. 2059–2065, 2006, doi. 10. 1093/TIN SINH HỌC/BTL355.  

Cập nhật vào 2022-05-26

hiện đang nghe Ashes on The Fire của KOHTA YAMAMOTO

chia sẻ bài đăng này trên

tín hiệu sinh học, javascript, scipy, xử lý tín hiệu
Quay lại . Trang chủ

Bộ lọc kỹ thuật số để xử lý tín hiệu trực tiếp trong Python Tăng tốc độ khám phá dữ liệu với bộ lọc dữ liệu đặc biệt trong Streamlit

Làm cách nào để phát hiện các đỉnh trong Python?

mảng #x và y. x = np. không gian trống [0, 10, 100].
#Tìm đỉnh. peaks = find_peaks[y, height = 1, threshold = 1, distance = 1] height = peaks[1]['peak_heights'] #list chứa chiều cao của các đỉnh. .
#Tìm cực tiểu. y2 = y*-1. .
# Vẽ đồ thị hàm số + cực đại và cực tiểu. vả = plt

Find_peaks hoạt động như thế nào?

Tìm các đỉnh bên trong tín hiệu dựa trên các thuộc tính của đỉnh . Hàm này lấy một mảng 1-D và tìm tất cả các cực đại cục bộ bằng cách so sánh đơn giản các giá trị lân cận. Theo tùy chọn, có thể chọn một tập hợp con của các đỉnh này bằng cách chỉ định các điều kiện cho các thuộc tính của đỉnh.

Find_peaks trả về cái gì?

pks = findpeaks[ data ] trả về một vectơ có cực đại cục bộ [đỉnh] của vectơ tín hiệu đầu vào, dữ liệu . Đỉnh cục bộ là một mẫu dữ liệu lớn hơn hai mẫu lân cận hoặc bằng Inf. Các đỉnh được xuất theo thứ tự xuất hiện.

Điểm nổi bật trong tìm đỉnh là gì?

Độ nổi bật của một đỉnh đo mức độ nổi bật của đỉnh do chiều cao nội tại và vị trí của nó so với các đỉnh khác . Một đỉnh thấp bị cô lập có thể nổi bật hơn một đỉnh cao hơn nhưng lại là một thành viên không đáng chú ý của dải cao.

Chủ Đề