python - 如果某些数据点是 NaN,如何拟合二维函数?

标签 python numpy missing-data astropy model-fitting

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

例如,我想在以下代码段中找到适合 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)

ResultI 在 Python 3.6 上使用 astropy 2.0.2numpy 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 和网格的相应“索引”。例如 boolean indexing :

notnans = np.isfinite(test)  # array containing True for finite values and False for nans/infs
c2_fit = fitter(c2_init, grid_wave[notnans], grid_pix[notnans], test[notnans])
print(c2_fit)

它仍然打印关于参数线性的警告,但值肯定是非零的:

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

这里的技巧是xy 和您的data 不需要是二维数组,它们可以是一维数组(由 bool 索引返回),只要它们“代表”二维网格即可。

以防万一您有包含 NaN 的“大区域”,这种方法可能不够好,因为装配器可以适应那里的任何东西。如果是这种情况,您可以使用 astropy.convolution.convolve 对这些区域进行插值,然后将 data 的 NaN 替换为 convolve 的结果:

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,卷积是不必要的。您可能需要比较这两种方法,看看哪一种方法能提供更“可靠”的结果。缺失值可能是拟合的真正问题。

关于python - 如果某些数据点是 NaN,如何拟合二维函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46924891/

相关文章:

python - 尝试在 Windows 上安装 pyodbc 时出现 "Microsoft Visual C++ … is required"错误

python - 如何使用 tqdm 遍历列表

python - 使用 Numpy 数组从结构返回数据

python - 多项式元素矩阵

r - 计算 R 中每年没有 N/A 的观察次数

python - 为什么不能在 python 中异或字节对象?

Python:将字符串解析为数组

r - 在样本外数据集上使用词袋分类器

julia - 在 Julia : Find the mean of an array with missing values

python - 与 numpy 数组相比,稀疏表示的输出不同