无法通过scipy.interpolate.griddata在n维网格上进行插值

时间:2019-04-22 09:39:57

标签: python numpy scipy grid interpolation

我有一个称为值的观察值数组,这些值来自以以下方式定义的函数:

values = np.array([oscillatory(i) for i in range(points.shape[0])])

值的形状为(65,1),点为要评估振荡函数的数组,形状为(65,7),7是在7维空间中充当维的某些特征(7只是任意数字)。

我正在尝试插值此空间中定义的一些任意点。 我尝试用以下方法定义这些点:

grid_x = np.random.uniform(0,10, (100,7))

但是没有用。显然是因为未正确定义网格,所以我尝试了:

grid_x= np.mgrid[-2:2, 5:99 , 4:5, 5:6, 5:7, 6:67, 7:67]

哪些不再起作用。 我通过以下方式调用插值函数:

grid_z1 = gdd(points, values, tuple(grid_x))

但是我总是遇到一个巨大的错误,我很难理解。

奇怪的是,如果我以随机方式定义点和值,则代码可以正常工作:

points = np.random.uniform(0,10, (65,3))
values = np.random.uniform(0,10,(points.shape[0],1))

grid_x= np.mgrid[0:2, 5:9 , 4:5]
grid_z1 = gdd(points, values, tuple(grid_x))

在这里,我只是尝试了3而不是7,因为它速度更快,但是原理保持不变。如果我在7维中定义它,代码也可以工作。 所以我的问题是: 1)如何在7个维度上运行我的初始代码? 2)如果数组具有相同的形状,为什么随机声明比其他声明更有效?

任何帮助将不胜感激。非常感谢。

我得到的错误如下:

    Traceback (most recent call last):
  File "/usr/lib/python3.6/code.py", line 91, in runcode
    exec(code, self.locals)
  File "<input>", line 2, in <module>
  File "/usr/local/lib/python3.6/dist-packages/scipy/interpolate/ndgriddata.py", line 222, in griddata
    rescale=rescale)
  File "interpnd.pyx", line 248, in scipy.interpolate.interpnd.LinearNDInterpolator.__init__
  File "qhull.pyx", line 1828, in scipy.spatial.qhull.Delaunay.__init__
  File "qhull.pyx", line 354, in scipy.spatial.qhull._Qhull.__init__
scipy.spatial.qhull.QhullError: QH6154 Qhull precision error: Initial simplex is flat (facet 1 is coplanar with the interior point)
While executing:  | qhull d Qbb Qt Qz Q12 Qc
Options selected for Qhull 2015.2.r 2016/01/18:
  run-id 526315618  delaunay  Qbbound-last  Qtriangulate  Qz-infinity-point
  Q12-no-wide-dup  Qcoplanar-keep  _pre-merge  _zero-centrum  Qinterior-keep
  Pgood  _max-width  4  Error-roundoff 1.2e-14  _one-merge 1.1e-13
  Visible-distance 7.3e-14  U-coplanar-distance 7.3e-14  Width-outside 1.5e-13
  _wide-facet 4.4e-13
precision problems (corrected unless 'Q0' or an error)
      2 flipped facets
      6 degenerate hyperplanes recomputed with gaussian elimination
     12 nearly singular or axis-parallel hyperplanes
      6 zero divisors during back substitute
    126 zero divisors during gaussian elimination
The input to qhull appears to be less than 4 dimensional, or a
computation has overflowed.
Qhull could not construct a clearly convex simplex from points:
- p2(v4):  -1.9     5     4 0.012
- p1(v3):  -1.9     5     4 0.0054
- p65(v2):     0   5.5   4.5     4
- p64(v1):     2     6     5     3
- p0(v0):    -2     5     4 -8.9e-16
The center point is coplanar with a facet, or a vertex is coplanar
with a neighboring facet.  The maximum round off error for
computing distances is 1.2e-14.  The center point, facets and distances
to the center point are as follows:
center point  -0.7625    5.309    4.309    1.407
facet p1 p65 p64 p0 distance=    0
facet p2 p65 p64 p0 distance= -8.9e-16
facet p2 p1 p64 p0 distance= -8.9e-16
facet p2 p1 p65 p0 distance= -8.9e-16
facet p2 p1 p65 p64 distance= -8.9e-16
These points either have a maximum or minimum x-coordinate, or
they maximize the determinant for k coordinates.  Trial points
are first selected from points that maximize a coordinate.
The min and max coordinates for each dimension are:
  0:        -2         2  difference=    4
  1:         5         6  difference=    1
  2:         4         5  difference=    1
  3:  -8.882e-16         4  difference=    4
If the input should be full dimensional, you have several options that
may determine an initial simplex:
  - use 'QJ'  to joggle the input and make it full dimensional
  - use 'QbB' to scale the points to the unit cube
  - use 'QR0' to randomly rotate the input for different maximum points
  - use 'Qs'  to search all points for the initial simplex
  - use 'En'  to specify a maximum roundoff error less than 1.2e-14.
  - trace execution with 'T3' to see the determinant for each point.
If the input is lower dimensional:
  - use 'QJ' to joggle the input and make it full dimensional
  - use 'Qbk:0Bk:0' to delete coordinate k from the input.  You should
    pick the coordinate with the least range.  The hull will have the
    correct topology.
  - determine the flat containing the points, rotate the points
    into a coordinate plane, and delete the other coordinates.
  - add one or more points to make the input full dimensional.

1 个答案:

答案 0 :(得分:1)

我认为问题在于您需要确保维度数量以及这些维度的“域”保持一致。插值到未采样的位置时,您将不会获得良好的结果。我认为您得到的错误与尝试在这些地方进行计算有关。

在这里,如何使scipy.interpolate.griddata文档中的示例适用于7维示例。我正在使用一个简单得多的函数,该函数仅对points数据中的“特征”进行求和:

import numpy as np

def func(data):
    return np.sum(data, axis=1)

grid = np.mgrid[0:1:5j, 0:1:5j, 0:1:5j, 0:1:5j, 0:1:5j, 0:1:5j, 0:1:5j]

points = np.random.rand(100, 7)
values = func(points)

请注意,网格覆盖了坐标points的整个范围。也就是说,由于points中的每一列的值都在0到1的范围内,因此我应该确保在相同的坐标上建立网格。

from scipy.interpolate import griddata
grid_z = griddata(points, values, tuple(grid), method='linear')

现在我有了这个

>>> grid_z[2, 2, 2, 2, 2, :, :]
array([[ nan,  nan,  nan,  nan,  nan],
       [ nan, 3.  , 3.25, 3.5 ,  nan],
       [ nan, 3.25, 3.5 , 3.75,  nan],
       [ nan, 3.5 , 3.75, 4.  ,  nan],
       [ nan,  nan,  nan,  nan,  nan]])

请注意,NaN有很多。如果您使用nearest作为方法,总会得到一个解决方案,但是当然linear插值需要在两点之间进行插值,因此超立方体的“边”无效(和7 -D空间有很多优势!)。