Python nội suy từ mảng

Tôi đang cố gắng chuyển đổi mã Python sang Julia sử dụng scipy.interpolate.interp1d và tôi đang gặp khó khăn trong việc tìm cách tốt nhất để thực hiện việc này trong Julia. Hàm interp1d thực hiện phép nội suy 1D dọc theo một chiều nhất định của mảng nhiều chiều

Tôi đã sử dụng Interpolations.jl nhưng cách tiếp cận của tôi có vẻ không phải là tốt nhất [xem bên dưới]. Có một câu hỏi tương tự được hỏi ba năm trước, nhưng câu trả lời được chấp nhận không cung cấp câu trả lời đơn giản

Đây là một ví dụ đơn giản về những gì tôi đang tìm kiếm

# Test data
x = [0.,  2., 5., 10., 11.]
y = repeat[x .^ 2, outer=[1, 3, 3]]

# We want to interpolate y [a 3D array] along the first dimension,
# so that the output is another 3D array
itp = interp1d[x, y; dims=1, k=1]

# Expected results
itp[2.0]
3×3 Matrix{Float64}:
 4.0  4.0  4.0
 4.0  4.0  4.0
 4.0  4.0  4.0

itp[3]
3×3 Matrix{Float64}:
 11.0  11.0  11.0
 11.0  11.0  11.0
 11.0  11.0  11.0

Dữ liệu của tôi đều ở dạng lưới không đều

Điều này có vẻ hiệu quả, nhưng tôi tự hỏi liệu đó có phải là cách tiếp cận tốt nhất không

itp = interpolate[[x, 1:3, 1:3], y, Gridded[Linear[]]]

itp[3, 1:3, 1:3]
3×3 Matrix{Float64}:
 11.0  11.0  11.0
 11.0  11.0  11.0
 11.0  11.0  11.0

Và có vẻ như với Gridded phép nội suy bậc cao nhất được hỗ trợ là tuyến tính
Bất kỳ ai khác có cách tiếp cận tốt hơn cho loại nội suy này?

Tương tự như lập chỉ mục, cũng chấp nhận dạng mảng, cho kết quả được nội suy dưới dạng mảng

# label lookup
In [4]: da.sel[time=[2, 3]]
Out[4]: 

array[[[ 0.974,  0.863,  0.675],
       [ 0.427,  0.141, -0.158]]]
Coordinates:
  * time     [time] int64 2 3
  * space    [space] float64 0.1 0.2 0.3

# interpolation
In [5]: da.interp[time=[2.5, 3.5]]
Out[5]: 

array[[[0.701, 0.502, 0.259],
       [  nan,   nan,   nan]]]
Coordinates:
  * space    [space] float64 0.1 0.2 0.3
  * time     [time] float64 2.5 3.5

Để nội suy dữ liệu bằng numpy. datetime64 tọa độ bạn có thể chuyển một chuỗi.

In [6]: da_dt64 = xr.DataArray[
   ...:     [1, 3], [["time", pd.date_range["1/1/2000", "1/3/2000", periods=2]]]
   ...: ]
   ...: 

In [7]: da_dt64.interp[time="2000-01-02"]
Out[7]: 

array[2.]
Coordinates:
    time     datetime64[ns] 2000-01-02

Dữ liệu nội suy có thể được hợp nhất vào dữ liệu gốc bằng cách chỉ định khoảng thời gian cần thiết

In [8]: da_dt64.interp[time=pd.date_range["1/1/2000", "1/3/2000", periods=3]]
Out[8]: 

array[[1., 2., 3.]]
Coordinates:
  * time     [time] datetime64[ns] 2000-01-01 2000-01-02 2000-01-03

Nội suy dữ liệu được lập chỉ mục bởi a cũng được cho phép. Xem ví dụ

Ghi chú

Hiện tại, phép nội suy của chúng tôi chỉ hoạt động đối với các lưới thông thường. Do đó, tương tự như , chỉ các tọa độ 1D dọc theo một chiều mới có thể được sử dụng làm tọa độ ban đầu được nội suy

Nội suy đa chiều

Like , chấp nhận nhiều tọa độ. Trong trường hợp này, nội suy nhiều chiều được thực hiện

# label lookup
In [9]: da.sel[time=2, space=0.1]
Out[9]: 

array[0.974]
Coordinates:
    time     int64 2
    space    float64 0.1

# interpolation
In [10]: da.interp[time=2.5, space=0.15]
Out[10]: 

array[0.601]
Coordinates:
    time     float64 2.5
    space    float64 0.15

Các tọa độ giống như mảng cũng được chấp nhận

# label lookup
In [11]: da.sel[time=[2, 3], space=[0.1, 0.2]]
Out[11]: 

array[[[0.974, 0.863],
       [0.427, 0.141]]]
Coordinates:
  * time     [time] int64 2 3
  * space    [space] float64 0.1 0.2

# interpolation
In [12]: da.interp[time=[1.5, 2.5], space=[0.15, 0.25]]
Out[12]: 

array[[[0.888, 0.867],
       [0.601, 0.381]]]
Coordinates:
  * time     [time] float64 1.5 2.5
  * space    [space] float64 0.15 0.25

phương pháp là một phím tắt hữu ích. Phương thức này nội suy một đối tượng xarray lên tọa độ của một đối tượng xarray khác. Ví dụ: nếu chúng tôi muốn tính toán sự khác biệt giữa hai s [

In [6]: da_dt64 = xr.DataArray[
   ...:     [1, 3], [["time", pd.date_range["1/1/2000", "1/3/2000", periods=2]]]
   ...: ]
   ...: 

In [7]: da_dt64.interp[time="2000-01-02"]
Out[7]: 

array[2.]
Coordinates:
    time     datetime64[ns] 2000-01-02
9 và
In [8]: da_dt64.interp[time=pd.date_range["1/1/2000", "1/3/2000", periods=3]]
Out[8]: 

array[[1., 2., 3.]]
Coordinates:
  * time     [time] datetime64[ns] 2000-01-01 2000-01-02 2000-01-03
0] ở trên các tọa độ hơi khác nhau,

In [13]: other = xr.DataArray[
   ....:     np.sin[0.4 * np.arange[9].reshape[3, 3]],
   ....:     [["time", [0.9, 1.9, 2.9]], ["space", [0.15, 0.25, 0.35]]],
   ....: ]
   ....: 

có thể là một ý kiến ​​hay trước tiên khi nội suy

In [6]: da_dt64 = xr.DataArray[
   ...:     [1, 3], [["time", pd.date_range["1/1/2000", "1/3/2000", periods=2]]]
   ...: ]
   ...: 

In [7]: da_dt64.interp[time="2000-01-02"]
Out[7]: 

array[2.]
Coordinates:
    time     datetime64[ns] 2000-01-02
9 để nó nằm trên cùng tọa độ của
In [8]: da_dt64.interp[time=pd.date_range["1/1/2000", "1/3/2000", periods=3]]
Out[8]: 

array[[1., 2., 3.]]
Coordinates:
  * time     [time] datetime64[ns] 2000-01-01 2000-01-02 2000-01-03
0, sau đó trừ nó đi. có thể được sử dụng cho một trường hợp như vậy,

# interpolate da along other's coordinates
In [14]: interpolated = da.interp_like[other]

In [15]: interpolated
Out[15]: 

array[[[0.787, 0.911,   nan],
       [0.912, 0.789,   nan],
       [0.348, 0.069,   nan]]]
Coordinates:
  * time     [time] float64 0.9 1.9 2.9
  * space    [space] float64 0.15 0.25 0.35

Bây giờ có thể tính toán chênh lệch một cách an toàn

In [8]: da_dt64.interp[time=pd.date_range["1/1/2000", "1/3/2000", periods=3]]
Out[8]: 

array[[1., 2., 3.]]
Coordinates:
  * time     [time] datetime64[ns] 2000-01-01 2000-01-02 2000-01-03
4

phương pháp nội suy

Chúng tôi sử dụng cho phép nội suy 1 chiều. Đối với nội suy nhiều chiều, trước tiên, một nỗ lực được thực hiện để phân tách phép nội suy thành một loạt các phép nội suy 1 chiều, trong trường hợp này được sử dụng. Nếu không thể thực hiện phân tách [e. g. với nội suy nâng cao], được sử dụng

Phương pháp nội suy có thể được chỉ định bởi đối số tùy chọn

In [8]: da_dt64.interp[time=pd.date_range["1/1/2000", "1/3/2000", periods=3]]
Out[8]: 

array[[1., 2., 3.]]
Coordinates:
  * time     [time] datetime64[ns] 2000-01-01 2000-01-02 2000-01-03
8

In [16]: da = xr.DataArray[
   ....:     np.sin[np.linspace[0, 2 * np.pi, 10]],
   ....:     dims="x",
   ....:     coords={"x": np.linspace[0, 1, 10]},
   ....: ]
   ....: 

In [17]: da.plot.line["o", label="original"]
Out[17]: []

In [18]: da.interp[x=np.linspace[0, 1, 100]].plot.line[label="linear [default]"]
Out[18]: []

In [19]: da.interp[x=np.linspace[0, 1, 100], method="cubic"].plot.line[label="cubic"]
Out[19]: []

In [20]: plt.legend[]
Out[20]: 

Các đối số từ khóa bổ sung có thể được chuyển đến các chức năng của scipy

# fill 0 for the outside of the original coordinates.
In [21]: da.interp[x=np.linspace[-0.5, 1.5, 10], kwargs={"fill_value": 0.0}]
Out[21]: 

array[[ 0.   ,  0.   ,  0.   ,  0.814,  0.604, -0.604, -0.814,  0.   ,  0.   ,  0.   ]]
Coordinates:
  * x        [x] float64 -0.5 -0.2778 -0.05556 0.1667 .. 0.8333 1.056 1.278 1.5

# 1-dimensional extrapolation
In [22]: da.interp[x=np.linspace[-0.5, 1.5, 10], kwargs={"fill_value": "extrapolate"}]
Out[22]: 

array[[-2.893, -1.607, -0.321,  0.814,  0.604, -0.604, -0.814,  0.321,  1.607,  2.893]]
Coordinates:
  * x        [x] float64 -0.5 -0.2778 -0.05556 0.1667 .. 0.8333 1.056 1.278 1.5

# multi-dimensional extrapolation
In [23]: da = xr.DataArray[
   ....:     np.sin[0.3 * np.arange[12].reshape[4, 3]],
   ....:     [["time", np.arange[4]], ["space", [0.1, 0.2, 0.3]]],
   ....: ]
   ....: 

In [24]: da.interp[
   ....:     time=4, space=np.linspace[-0.1, 0.5, 10], kwargs={"fill_value": "extrapolate"}
   ....: ]
   ....: 
Out[24]: 

array[[ 0.805,  0.497,  0.189, -0.119, -0.427, -0.718, -0.991, -1.264, -1.538, -1.811]]
Coordinates:
    time     int64 4
  * space    [space] float64 -0.1 -0.03333 0.03333 0.1 .. 0.3 0.3667 0.4333 0.5

Nội suy nâng cao

chấp nhận tương tự như , cho phép chúng tôi nội suy nâng cao hơn. Dựa trên kích thước của tọa độ mới được chuyển đến, kích thước của kết quả được xác định

Ví dụ: nếu bạn muốn nội suy một mảng hai chiều dọc theo một chiều cụ thể, như minh họa bên dưới, bạn có thể chuyển hai s 1 chiều với một chiều chung làm tọa độ mới

Ví dụ

# label lookup
In [4]: da.sel[time=[2, 3]]
Out[4]: 

array[[[ 0.974,  0.863,  0.675],
       [ 0.427,  0.141, -0.158]]]
Coordinates:
  * time     [time] int64 2 3
  * space    [space] float64 0.1 0.2 0.3

# interpolation
In [5]: da.interp[time=[2.5, 3.5]]
Out[5]: 

array[[[0.701, 0.502, 0.259],
       [  nan,   nan,   nan]]]
Coordinates:
  * space    [space] float64 0.1 0.2 0.3
  * time     [time] float64 2.5 3.5
0

trong đó các giá trị trên tọa độ ban đầu

# label lookup
In [9]: da.sel[time=2, space=0.1]
Out[9]: 

array[0.974]
Coordinates:
    time     int64 2
    space    float64 0.1

# interpolation
In [10]: da.interp[time=2.5, space=0.15]
Out[10]: 

array[0.601]
Coordinates:
    time     float64 2.5
    space    float64 0.15
4 thu được bằng phép nội suy 2 chiều và được ánh xạ dọc theo một chiều mới
# label lookup
In [9]: da.sel[time=2, space=0.1]
Out[9]: 

array[0.974]
Coordinates:
    time     int64 2
    space    float64 0.1

# interpolation
In [10]: da.interp[time=2.5, space=0.15]
Out[10]: 

array[0.601]
Coordinates:
    time     float64 2.5
    space    float64 0.15
5. Vì không có đối số từ khóa nào được chuyển đến quy trình nội suy nên không có phép ngoại suy nào được thực hiện dẫn đến giá trị
# label lookup
In [9]: da.sel[time=2, space=0.1]
Out[9]: 

array[0.974]
Coordinates:
    time     int64 2
    space    float64 0.1

# interpolation
In [10]: da.interp[time=2.5, space=0.15]
Out[10]: 

array[0.601]
Coordinates:
    time     float64 2.5
    space    float64 0.15
6

Nếu bạn muốn thêm tọa độ vào thứ nguyên mới

# label lookup
In [9]: da.sel[time=2, space=0.1]
Out[9]: 

array[0.974]
Coordinates:
    time     int64 2
    space    float64 0.1

# interpolation
In [10]: da.interp[time=2.5, space=0.15]
Out[10]: 

array[0.601]
Coordinates:
    time     float64 2.5
    space    float64 0.15
5, bạn có thể cung cấp s với tọa độ. Phép ngoại suy có thể đạt được bằng cách chuyển các đối số bổ sung cho hàm
# label lookup
In [9]: da.sel[time=2, space=0.1]
Out[9]: 

array[0.974]
Coordinates:
    time     int64 2
    space    float64 0.1

# interpolation
In [10]: da.interp[time=2.5, space=0.15]
Out[10]: 

array[0.601]
Coordinates:
    time     float64 2.5
    space    float64 0.15
9 của SciPy,

# label lookup
In [4]: da.sel[time=[2, 3]]
Out[4]: 

array[[[ 0.974,  0.863,  0.675],
       [ 0.427,  0.141, -0.158]]]
Coordinates:
  * time     [time] int64 2 3
  * space    [space] float64 0.1 0.2 0.3

# interpolation
In [5]: da.interp[time=[2.5, 3.5]]
Out[5]: 

array[[[0.701, 0.502, 0.259],
       [  nan,   nan,   nan]]]
Coordinates:
  * space    [space] float64 0.1 0.2 0.3
  * time     [time] float64 2.5 3.5
1

Để biết chi tiết về lập chỉ mục nâng cao, xem

Nội suy mảng với NaN

Chúng tôi làm việc với các mảng có NaN giống như cách mà scipy. nội suy. interp1d và scipy. nội suy. thực tập làm. Các phương thức

# label lookup
In [11]: da.sel[time=[2, 3], space=[0.1, 0.2]]
Out[11]: 

array[[[0.974, 0.863],
       [0.427, 0.141]]]
Coordinates:
  * time     [time] int64 2 3
  * space    [space] float64 0.1 0.2

# interpolation
In [12]: da.interp[time=[1.5, 2.5], space=[0.15, 0.25]]
Out[12]: 

array[[[0.888, 0.867],
       [0.601, 0.381]]]
Coordinates:
  * time     [time] float64 1.5 2.5
  * space    [space] float64 0.15 0.25
1 và
# label lookup
In [11]: da.sel[time=[2, 3], space=[0.1, 0.2]]
Out[11]: 

array[[[0.974, 0.863],
       [0.427, 0.141]]]
Coordinates:
  * time     [time] int64 2 3
  * space    [space] float64 0.1 0.2

# interpolation
In [12]: da.interp[time=[1.5, 2.5], space=[0.15, 0.25]]
Out[12]: 

array[[[0.888, 0.867],
       [0.601, 0.381]]]
Coordinates:
  * time     [time] float64 1.5 2.5
  * space    [space] float64 0.15 0.25
2 trả về các mảng bao gồm NaN, trong khi các phương thức khác như
# label lookup
In [11]: da.sel[time=[2, 3], space=[0.1, 0.2]]
Out[11]: 

array[[[0.974, 0.863],
       [0.427, 0.141]]]
Coordinates:
  * time     [time] int64 2 3
  * space    [space] float64 0.1 0.2

# interpolation
In [12]: da.interp[time=[1.5, 2.5], space=[0.15, 0.25]]
Out[12]: 

array[[[0.888, 0.867],
       [0.601, 0.381]]]
Coordinates:
  * time     [time] float64 1.5 2.5
  * space    [space] float64 0.15 0.25
3 hoặc
# label lookup
In [11]: da.sel[time=[2, 3], space=[0.1, 0.2]]
Out[11]: 

array[[[0.974, 0.863],
       [0.427, 0.141]]]
Coordinates:
  * time     [time] int64 2 3
  * space    [space] float64 0.1 0.2

# interpolation
In [12]: da.interp[time=[1.5, 2.5], space=[0.15, 0.25]]
Out[12]: 

array[[[0.888, 0.867],
       [0.601, 0.381]]]
Coordinates:
  * time     [time] float64 1.5 2.5
  * space    [space] float64 0.15 0.25
4 trả về tất cả các mảng NaN

# label lookup
In [4]: da.sel[time=[2, 3]]
Out[4]: 

array[[[ 0.974,  0.863,  0.675],
       [ 0.427,  0.141, -0.158]]]
Coordinates:
  * time     [time] int64 2 3
  * space    [space] float64 0.1 0.2 0.3

# interpolation
In [5]: da.interp[time=[2.5, 3.5]]
Out[5]: 

array[[[0.701, 0.502, 0.259],
       [  nan,   nan,   nan]]]
Coordinates:
  * space    [space] float64 0.1 0.2 0.3
  * time     [time] float64 2.5 3.5
2

Để tránh điều này, bạn có thể loại bỏ NaN bằng , sau đó thực hiện phép nội suy

# label lookup
In [4]: da.sel[time=[2, 3]]
Out[4]: 

array[[[ 0.974,  0.863,  0.675],
       [ 0.427,  0.141, -0.158]]]
Coordinates:
  * time     [time] int64 2 3
  * space    [space] float64 0.1 0.2 0.3

# interpolation
In [5]: da.interp[time=[2.5, 3.5]]
Out[5]: 

array[[[0.701, 0.502, 0.259],
       [  nan,   nan,   nan]]]
Coordinates:
  * space    [space] float64 0.1 0.2 0.3
  * time     [time] float64 2.5 3.5
3

Nếu NaN được phân phối ngẫu nhiên trong mảng đa chiều của bạn, việc loại bỏ tất cả các cột chứa nhiều NaN có thể làm mất một lượng thông tin đáng kể. Trong trường hợp như vậy, bạn có thể điền NaN bằng , tương tự như

# label lookup
In [4]: da.sel[time=[2, 3]]
Out[4]: 

array[[[ 0.974,  0.863,  0.675],
       [ 0.427,  0.141, -0.158]]]
Coordinates:
  * time     [time] int64 2 3
  * space    [space] float64 0.1 0.2 0.3

# interpolation
In [5]: da.interp[time=[2.5, 3.5]]
Out[5]: 

array[[[0.701, 0.502, 0.259],
       [  nan,   nan,   nan]]]
Coordinates:
  * space    [space] float64 0.1 0.2 0.3
  * time     [time] float64 2.5 3.5
4

Điều này lấp đầy NaN bằng cách nội suy dọc theo thứ nguyên đã chỉ định. Sau khi điền NaN, bạn có thể nội suy

# label lookup
In [4]: da.sel[time=[2, 3]]
Out[4]: 

array[[[ 0.974,  0.863,  0.675],
       [ 0.427,  0.141, -0.158]]]
Coordinates:
  * time     [time] int64 2 3
  * space    [space] float64 0.1 0.2 0.3

# interpolation
In [5]: da.interp[time=[2.5, 3.5]]
Out[5]: 

array[[[0.701, 0.502, 0.259],
       [  nan,   nan,   nan]]]
Coordinates:
  * space    [space] float64 0.1 0.2 0.3
  * time     [time] float64 2.5 3.5
5

Để biết chi tiết về , xem

Thí dụ

Hãy xem cách hoạt động trên dữ liệu thực

# label lookup
In [4]: da.sel[time=[2, 3]]
Out[4]: 

array[[[ 0.974,  0.863,  0.675],
       [ 0.427,  0.141, -0.158]]]
Coordinates:
  * time     [time] int64 2 3
  * space    [space] float64 0.1 0.2 0.3

# interpolation
In [5]: da.interp[time=[2.5, 3.5]]
Out[5]: 

array[[[0.701, 0.502, 0.259],
       [  nan,   nan,   nan]]]
Coordinates:
  * space    [space] float64 0.1 0.2 0.3
  * time     [time] float64 2.5 3.5
6

Nội suy nâng cao của chúng tôi có thể được sử dụng để ánh xạ lại dữ liệu sang tọa độ mới. Xét tọa độ mới x và z trên mặt phẳng hai chiều. Việc ánh xạ lại có thể được thực hiện như sau

Nội suy mảng là gì?

Nội suy mảng cung cấp một mô hình hoặc chuyển đổi giữa phản hồi mảng thực và mong muốn . Nếu phản ứng thực của mảng trở nên méo mó hơn so với mong muốn hoặc vùng được xem xét của trường nhìn của mảng tăng lên, thì các phương pháp phi tuyến trở nên cần thiết.

Làm thế nào để interp1d hoạt động trong Python?

Hàm interp1d[] được dùng để nội suy phân phối có 1 biến . Nó lấy các điểm x và y và trả về một hàm có thể gọi được có thể được gọi với new x và trả về y tương ứng.

Hàm nội suy trong Python NumPy là gì?

Hàm NumPy interp[] trong Python còn được gọi là phép nội suy trả về phép nội suy tuyến tính từng phần một chiều cho một hàm có các điểm dữ liệu rời rạc đã cho [xp, fp]. It is one-dimensional linear interpolation for monotonically increasing sample points.

SciPy nội suy trong Python là gì?

Nội suy là một kỹ thuật xây dựng các điểm dữ liệu giữa các điểm dữ liệu đã cho. các scipy. nội suy là một mô-đun trong Python SciPy bao gồm các lớp, hàm spline và các lớp nội suy đơn biến và đa biến .

Chủ Đề