2009-05-24 44 views
6

Tôi có hơn 20 bảng tương tự bảng 1. Trong đó tất cả các chữ cái đại diện cho giá trị thực.Lưu trữ dữ liệu để dễ dàng nội suy dữ liệu trong Python

Table 1: 
$/cars |<1 | 2 | 3 | 4+ 
<10,000 | a | b | c | d 
20,000 | e | f | g | h 
30,000 | i | j | k | l 
40,000+ | m | n | o | p 

Một đầu vào của người dùng có thể là ví dụ, (2,4, 24594) là giá trị giữa f, g, j và k. Định nghĩa hàm Python của tôi và mã giả để tính toán nội suy tuyến tính này như sau.

def bilinear_interpolation(x_in, y_in, x_high, x_low, y_low, y_high): 
    # interpolate with respect to x 
    # interpolate with respect to y 
    # return result 

Làm thế nào tôi nên lưu trữ các dữ liệu từ bảng 1 (một tập tin, một dict, tuple của các bộ, hoặc dict danh sách), vì vậy tôi có thể thực hiện nội suy song tuyến một cách hiệu quả nhất và chính xác?

Trả lời

7

Nếu bạn muốn giải pháp hiệu quả về mặt tính toán nhất mà tôi có thể nghĩ và không bị giới hạn trong thư viện chuẩn, thì tôi khuyên bạn nên dùng scipy/numpy. Đầu tiên, lưu trữ mảng a..p dưới dạng mảng numpy 2D và sau đó cả mảng $ 4k-10k và 1-4 là mảng có khối lượng 1D. Sử dụng interpolate.interp1d của sciper nếu cả hai mảng 1D đều tăng lên một cách đơn điệu, hoặc interpolate.bsplrep (biểu diễn dòng luân phiên hai chiều) nếu không và các mảng ví dụ của bạn nhỏ như ví dụ của bạn. Hoặc đơn giản là viết của riêng bạn và không bận tâm với scipy. Dưới đây là một số ví dụ:

# this follows your pseudocode most closely, but it is *not* 
# the most efficient since it creates the interpolation 
# functions on each call to bilinterp 
from scipy import interpolate 
import numpy 
data = numpy.arange(0., 16.).reshape((4,4)) #2D array 
prices = numpy.arange(10000., 50000., 10000.) 
cars = numpy.arange(1., 5.) 
def bilinterp(price,car): 
    return interpolate.interp1d(cars, interpolate.interp1d(prices, a)(price))(car) 
print bilinterp(22000,2) 

Lần cuối cùng tôi đã kiểm tra (một phiên bản của scipy từ năm 2007-ish) nó chỉ làm việc cho đơn điệu tăng mảng của x và y)

cho mảng nhỏ như mảng 4x4 này , Tôi nghĩ bạn muốn sử dụng điều này: http://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.bisplrep.html#scipy.interpolate.bisplrep sẽ xử lý các bề mặt được tạo hình thú vị hơn và chỉ cần tạo chức năng một lần. Đối với mảng lớn hơn, tôi nghĩ bạn muốn điều này (không chắc chắn nếu điều này có cùng hạn chế như interp1d): http://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.interp2d.html#scipy.interpolate.interp2d nhưng cả hai đều yêu cầu cấu trúc dữ liệu khác nhau và tiết hơn so với ba mảng trong ví dụ trên.

+0

xin vui lòng đưa ra một số ví dụ, tôi có vấn đề tương tự nhưng không thể bẻ khóa trong O (log n) –

+0

Tôi thích điều này vì tôi đã sử dụng gọn gàng trong đơn đăng ký của mình: D cảm ơn bạn – dassouki

0

Không có gì đặc biệt về nội suy song tuyến làm cho trường hợp sử dụng của bạn đặc biệt kỳ quặc; bạn chỉ cần thực hiện hai lần tra cứu (đối với các đơn vị lưu trữ của các hàng/cột đầy đủ) hoặc bốn lần tra cứu (đối với lưu trữ kiểu mảng). Phương pháp hiệu quả nhất phụ thuộc vào các mẫu truy cập của bạn và cấu trúc của dữ liệu.

Nếu ví dụ của bạn thực sự là đại diện, với tổng số 16 mục nhập, bạn có thể lưu trữ nó theo bất kỳ cách nào bạn muốn và nó sẽ đủ nhanh cho bất kỳ loại tải sane nào.

3

Tôi sẽ giữ danh sách được sắp xếp của cột đầu tiên và sử dụng mô-đun bisect trong thư viện chuẩn để tìm các giá trị - đó là cách tốt nhất để có chỉ số ngay lập tức thấp hơn và ngay lập tức cao hơn. Mỗi cột khác có thể được giữ như một danh sách khác song song với cột này.

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