Python 如果某些数据点是非整数,如何拟合二维函数?

Python 如果某些数据点是非整数,如何拟合二维函数?,python,numpy,missing-data,astropy,model-fitting,Python,Numpy,Missing Data,Astropy,Model Fitting,我正在尝试将二维曲面拟合到数据。更具体地说,我想找到一个将像素坐标映射到波长坐标的函数,就像IRAF中的FITCOORDS一样 例如,我想在下面的代码片段中找到fit totest数组: import numpy as np from astropy.modeling.models import Chebyshev2D from astropy.modeling.fitting import LevMarLSQFitter #%% test = np.array([[7473, 7040, 66

我正在尝试将二维曲面拟合到数据。更具体地说,我想找到一个将像素坐标映射到波长坐标的函数,就像IRAF中的FITCOORDS一样

例如,我想在下面的代码片段中找到fit to
test
数组:

import numpy as np
from astropy.modeling.models import Chebyshev2D
from astropy.modeling.fitting import LevMarLSQFitter
#%%
test = np.array([[7473, 7040, 6613, 6183, 5753, 5321, 4888],
   [7474, 7042, 6616, 6186, np.nan, 5325, 4893],
   [7476, 7044, 6619, 6189, 5759, 5328, 4897],
   [7479, 7047, np.nan, 6192, 5762, 5331, 4900]])
grid_pix, grid_wave = np.mgrid[:4, :7]
fitter = LevMarLSQFitter()
c2_init = Chebyshev2D(x_degree=3, y_degree=3)
c2_fit = fitter(c2_init, grid_wave, grid_pix, test)
print(c2_fit)
在Python 3.6上使用astropy 2.0.2和numpy 1.13.3的结果:

Model: Chebyshev2D
Inputs: ('x', 'y')
Outputs: ('z',)
Model set size: 1
X-Degree: 3
Y-Degree: 3
Parameters:
    c0_0 c1_0 c2_0 c3_0 c0_1 c1_1 c2_1 c3_1 c0_2 c1_2 c2_2 c3_2 c0_3 c1_3 c2_3 c3_3
    ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
     0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
WARNING: Model is linear in parameters; consider using linear fitting methods. [astropy.modeling.fitting]
很明显,这个装置从来都不起作用

如果我将
np.nan
更改为某些值,拟合将按预期工作(例如,手动将
np.nan
更改为0、1等)


我应该如何得到合理的结果?我可以让装配工忽略
np.nan
值吗?

您只需删除数据中的
nan
s以及网格中相应的“索引”。例如:

它仍然会打印一条关于参数中线性的警告,但这些值肯定不是零:

Model: Chebyshev2D
Inputs: ('x', 'y')
Outputs: ('z',)
Model set size: 1
X-Degree: 3
Y-Degree: 3
Parameters:
         c0_0          c1_0           c2_0      ...       c2_3            c3_3      
    ------------- -------------- -------------- ... --------------- ----------------
    7473.01546325 -431.633443323 0.471726190475 ... 0.0229037267082 -0.0012077294686
这里的技巧是,
x
y
和您的
数据
不需要是2D数组,它们可以是1D数组(通过布尔索引返回),只要它们“表示”2D网格即可

如果你有包含NAN的“大区域”,这种方法可能不够好,因为装配工可以在那里装配任何东西。如果是这种情况,您可以使用
astropy.convolution.convolve
在这些区域上插值,然后用
convolve
的结果替换
数据的NaN:

from astropy.convolution import convolve
# Just for illustration I used a 5x5 mean filter here, the size must be adjusted
# depending on the size of all-nan-regions in your data.
mean_convolved = convolve(test, np.ones((5, 5)), boundary='extend')
# Replacing NaNs in test with the mean_convolved values:
nan_mask = np.isnan(test)
test[nan_mask] = mean_convolved[nan_mask]

# Now pass test to the fitter:
c2_fit = fitter(c2_init, grid_wave, grid_pix, test)

然而,对于一些稀疏分布的NAN,不需要卷积。您可能需要比较这两种方法,看看哪一种方法给出的结果更“可信”。缺少值可能是拟合的一个真正问题。

只需删除nan,而不是用伪值替换它们?@Julien我如何从数组中删除
np.nan
example@Julien不,我的意思是应该用哪个值替换
np.nan
?我在一些
(x,y)
点上没有数据(
z
),哦!这是如此简单,正是我要找的!非常感谢你:D
from astropy.convolution import convolve
# Just for illustration I used a 5x5 mean filter here, the size must be adjusted
# depending on the size of all-nan-regions in your data.
mean_convolved = convolve(test, np.ones((5, 5)), boundary='extend')
# Replacing NaNs in test with the mean_convolved values:
nan_mask = np.isnan(test)
test[nan_mask] = mean_convolved[nan_mask]

# Now pass test to the fitter:
c2_fit = fitter(c2_init, grid_wave, grid_pix, test)