2012-09-02 25 views
6

numpy.interp rất thuận tiện và tương đối nhanh. Trong các ngữ cảnh nhất định, tôi muốn so sánh đầu ra của nó với một biến thể không được nội suy trong đó các giá trị thưa thớt được truyền đi (trong đầu ra "đậm đặc hơn") và kết quả là hằng số piecewise giữa các đầu vào thưa thớt. Hàm tôi muốn cũng có thể được gọi là trình chuyển đổi "thưa thớt -> dày đặc" sao chép giá trị thưa thớt mới nhất cho đến khi nó tìm thấy giá trị sau (một loại nội suy rỗng như thể không có thời gian/khoảng cách nào đã trôi qua từ giá trị trước đó).Thay thế drop-in tốt nhất cho numpy.interp là gì nếu tôi muốn nội suy rỗng (hằng số piecewise)?

Thật không may, không dễ dàng tinh chỉnh nguồn cho numpy.interp vì nó chỉ là trình bao bọc xung quanh chức năng được biên dịch. Tôi có thể viết bản thân mình bằng cách sử dụng vòng lặp Python, nhưng hy vọng sẽ tìm thấy một cách tốc độ C để giải quyết vấn đề.

Cập nhật: giải pháp dưới đây (scipy.interpolate.interp1d với kind='zero') là khá chậm và mất hơn 10 giây cho mỗi cuộc gọi (ví dụ đầu vào 500k trong chiều dài đó là 50% dân cư). Nó thực hiện kind='zero' bằng cách sử dụng một số không spline và các cuộc gọi đến spleval là rất chậm. Tuy nhiên, mã nguồn cho kind='linear' (tức là nội suy mặc định) cung cấp một mẫu tuyệt vời để giải quyết vấn đề bằng cách sử dụng gọn gàng thẳng (thay đổi tối thiểu là đặt slope=0). Mã đó cho thấy cách sử dụng numpy.searchsorted để giải quyết vấn đề và thời gian chạy tương tự như gọi numpy.interp, do đó, vấn đề được giải quyết bằng cách tinh chỉnh việc thực hiện nội suy tuyến tính scipy.interpolate.interp1d để bỏ qua bước nội suy (độ dốc! = 0 trộn các giá trị lân cận).

+0

Chỉ muốn nói cảm ơn cho bản cập nhật - Tôi muốn có một nội suy bằng không với 'numpy' mà không có toàn bộ sự phụ thuộc vào' scipy', và cập nhật bài viết của bạn chỉ ra cách để thực hiện nó. Trong một thử nghiệm nhỏ tôi đã thực hiện, 'numpy' 1.5.1: đã cài đặt 0.8.0' scipy' với '_fitpack.so' làm thử nghiệm của tôi trong khoảng 308 đến 508 μs; trong khi 'numpy' chỉ tấn công tuyến tính với' độ dốc = 0' làm tương tự trong 491 đến 778 μs - vì vậy đối với tôi nó là chậm hơn; nhưng không phải tất cả! Cảm ơn một lần nữa - chúc mừng! – sdaau

Trả lời

3

scipy.interpolate.interp1d có thể thực hiện tất cả các loại nội suy: ‘tuyến tính’, ’gần nhất’, ‘số không’, ‘dấu gạch chéo’, ‘bậc hai’, ‘khối’.

Vui lòng kiểm tra tài liệu: http://docs.scipy.org/doc/scipy-0.10.1/reference/generated/scipy.interpolate.interp1d.html#scipy.interpolate.interp1d

+0

Cảm ơn, loại = 'không' giải quyết được vấn đề của tôi. –

+1

Thật không may là nó rất chậm cho mỗi cập nhật cho câu hỏi. Đây là một câu trả lời hoàn toàn hợp lệ nhưng việc thực hiện Spline cơ bản không hiệu quả lắm. –

0

Chỉ cần hoàn thành: Giải pháp cho vấn đề là đoạn mã sau đó tôi đã có thể viết với sự giúp đỡ của các gợi ý được đưa ra trong câu trả lời Cập nhật:

def interpolate_constant(x, xp, yp): 
    indices = np.searchsorted(xp, x, side='right') 
    y = np.concatenate(([0], yp)) 
    return y[indices] 
0

Tôi hoàn toàn đồng ý rằng loại = 'không' là cực kỳ chậm; đối với một tập dữ liệu lớn có hàng triệu hàng, nó có thể chậm hơn gấp 1000 lần so với phương pháp 'tuyến tính'. Đối với nội suy "không đổi bên trái" - sử dụng giá trị mới nhất - mã sau hoạt động:

def approx(x, y, xout, yleft=np.nan, yright=np.nan): 
    xoutIdx  = np.searchsorted(x, xout, side='right')-1 
    return (np.where(xout<x[0], yleft, np.where(xout>x[-1], yright, y[xoutIdx]))) 

Đến từ nền R, giá trị này tương đương với khoảng R = f = 0. Tôi đã không tìm thấy một cách sạch sẽ để làm điều này cho nội suy "đúng liên tục" vì np.searchsorted python với side = 'right' đẩy một chỉ số trở lại nếu giá trị xout khớp chính xác với một giá trị trong x ...

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