2014-07-05 49 views
6

Hi những người đam mê python!SciPy medfilt kết quả sai

Tôi hiện đang làm việc với bộ lọc tín hiệu cho mục đích nghiên cứu và quyết định sử dụng SciPy. Không có gì đặc biệt, chỉ tự động hóa công việc thường ngày.

Vì vậy, đây là mã

from scipy.signal import medfilt 
print(medfilt([2,6,5,4,0,3,5,7,9,2,0,1], 5)) 

Nhưng vấn đề là sequense trở được tính sai

SciPy: [ 2. 4. 4. 4. 4. 4. 5. 5. 5. 2. 1. 0.] 
Me : [ 5. 4.5 4. 4. 4. 4. 5. 5. 5. 2. 1.5 1.] 

Nó có vẻ là, các nhà phát triển của gói điều sai lầm một cách chi tiết. Khi khẩu độ (hạt nhân về SciPy) lớn hơn cửa sổ để phân tích, có một quy tắc lọc khác.

Ví dụ: kernel=5 chuỗi được lọc [2, 6, 5] có số trung vị 5 và không bằng 2 như SciPy được tính không? Và theo cách tương tự, nếu kernel=5 đối với số [2,6,5,4] số trung vị là 5 và 4, chúng tôi cần tính trung bình giữa chúng, vì vậy, trung bình là 4,5.

Ai đó có thể giải thích cho tôi biết ai có kết quả đúng trong trường hợp đó không?

Trả lời

13

Tôi tin rằng cả bạn và SciPy đều có kết quả chính xác. Sự khác biệt là ở những gì xảy ra ở ranh giới, nhưng tôi tin rằng cả bạn và SciPy đều có những lựa chọn hợp lệ.

Câu hỏi là điều gì sẽ xảy ra khi cửa sổ trượt của bạn ở các cạnh và không có dữ liệu hợp lệ để sử dụng để điền vào cửa sổ trượt của bạn.

Bạn đã chọn lấy phần trung bình của phần hợp lệ của cửa sổ trượt, điều này có ý nghĩa, nhưng có thể thêm một số thiên vị vì các điểm cạnh của bạn vượt quá so với tất cả các điểm khác.

SciPy thay vì chọn mở rộng tín hiệu ở một trong hai cạnh bằng số không đệm. Vì vậy, về ranh giới, scipy được về cơ bản tính

>>> np.median([0, 0, 2, 6, 5]) 
2.0 
>>> np.median([0, 2, 6, 5, 4]) 
4.0 
>>> np.median([9, 2, 0, 1, 0]) 
1.0 
>>> np.median([2, 0, 1, 0, 0]) 
0.0 

Lý do tại sao scipy thực hiện điều này là gần như chắc chắn tốc độ liên quan: nó được tối ưu hóa để làm điều tương tự nhiều lần, và nó là dễ dàng hơn nhiều để tối ưu hóa median cho một bó toàn bộ các mảng gồm 5 phần tử hơn là tối ưu hóa nó cho toàn bộ một mảng gồm 5 phần tử, và cũng có hai mảng 4 phần tử và hai mảng 3 phần tử. Chắc chắn có một lập luận được thực hiện rằng nó không nên đệm bằng số không, nhưng thay vào đó với các giá trị biên, nhưng cần lưu ý rằng không có chiến lược ranh giới nào là hoàn hảo; cách lý tưởng để giải quyết các vấn đề biên là phụ thuộc vào tín hiệu cụ thể của bạn.

Nếu bạn thấy Wikipedia's description of median filters, chúng sẽ mở rộng tín hiệu ở hai cạnh bằng cách đệm nó với giá trị ở các cạnh, điều này cũng có vẻ hợp lý. Họ cũng lưu ý ba cách khác để xử lý các vấn đề biên giới:

  • Tránh xử lý các ranh giới, có hoặc không cắt đường viền tín hiệu sau đó.
  • Tìm nạp các mục nhập từ các vị trí khác trong tín hiệu. Ví dụ: với hình ảnh, các mục từ ranh giới dọc hoặc dọc có thể được chọn.
  • Thu hẹp cửa sổ gần ranh giới, sao cho mọi cửa sổ đều đầy (như bạn đã làm.)

Cuối cùng, bạn thực sự cần thử các tùy chọn khác nhau và xem tùy chọn nào phù hợp nhất với tín hiệu của bạn. Giả định cốt lõi của loại lọc này là tín hiệu của bạn sẽ khá lớn và vấn đề biên không bao giờ là quan trọng (vì phần lớn tín hiệu không tồn tại trên ranh giới). Nó sẽ là tốt đẹp nếu SciPy cho phép bạn chọn những gì nó nên làm ở ranh giới, mặc dù!

+0

Chỉ cần mở rộng một chút về câu trả lời này, những người tìm kiếm các chức năng trung gian cán thay thế có thể xem xét: Gấu trúc trung bình: http://pandas.pydata.org/pandas-docs/stable/computation.html# di chuyển-cán-thống kê-khoảnh khắc và scipy.ndimage: http://docs.scipy.org/doc/scipy-0.15.1/reference/generated/scipy.ndimage.filters.median_filter.html – ConnectedSystems

Các vấn đề liên quan