Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 大numpy阵列的球面插值_Python_Numpy_Interpolation_Nan - Fatal编程技术网

Python 大numpy阵列的球面插值

Python 大numpy阵列的球面插值,python,numpy,interpolation,nan,Python,Numpy,Interpolation,Nan,我有一个numpy数组,它有8个字段,有2000万个样本 这些字段是[时间,X,Y,Z,QW,QX,QY,QZ] 其中x,y,z是空间点,QW,QX,QY,QZ是四元数 有两种不同的样本,一种包含[时间,X,Y,Z]数据,另一种包含[时间,QW,QX,QY,QZ]。由于数组是同质的,第一种类型的样本看起来像[时间,X,Y,Z,nan,nan,nan,nan],第二种类型的样本看起来像[时间,nan,nan,nan,nan,QW,QX,QY,QZ]。还有更多的[time,X,Y,Z,nan,nan

我有一个numpy数组,它有8个字段,有2000万个样本

这些字段是
[时间,X,Y,Z,QW,QX,QY,QZ]
其中x,y,z是空间点,QW,QX,QY,QZ是四元数

有两种不同的样本,一种包含
[时间,X,Y,Z]
数据,另一种包含
[时间,QW,QX,QY,QZ]
。由于数组是同质的,第一种类型的样本看起来像
[时间,X,Y,Z,nan,nan,nan,nan]
,第二种类型的样本看起来像
[时间,nan,nan,nan,nan,QW,QX,QY,QZ]
。还有更多的
[time,X,Y,Z,nan,nan,nan,nan]类型的示例
。阵列中只有20000个
[时间、nan、nan、nan、QW、QX、QY、QZ]
类型的样本

因此,该数组看起来像:

[time,nan,nan,nan,QW,QX,QY,QZ]
[time,X,Y,Z,nan,nan,nan,nan]
[time,X,Y,Z,nan,nan,nan,nan]
[time,X,Y,Z,nan,nan,nan,nan]
...
[time,X,Y,Z,nan,nan,nan,nan]
[time,nan,nan,nan,QW,QX,QY,QZ]
[time,X,Y,Z,nan,nan,nan,nan]
...
[time,nan,nan,nan,QW,QX,QY,QZ]
我的问题是,如何使用pyquaternion中的SLERP(球面线性插值)来插值观测值之间的QW、QX、QY、QZ值

四元数插值函数采用参数(四元数1、四元数2、比率)

其中比率为(时间点时间四元数1)/(时间四元数2时间四元数1)

问题是,对于给定的时间点x、y、z,如何快速搜索最近的上下四元数观测值

例如,我尝试过1000000点:

data.shape=(20000000,8)

quat1=Quaternion(数据[np.where((数据[1000000,0]>=data[:,0])和(~np.isnan(数据[:,4]))[0][1],4:8])

quat2=四元数(data[np.其中((data[1000000,0])我通常不使用四元数,因此我没有任何可用的实现。但是,由于问题似乎是如何找到要插值的点,这与四元数没有直接关系

该方法迭代成对的可用观测值,并插值介于两者之间的所有样本:

# Column 0: time
# Columns 1 - 3: quaternion (well, not really, but it should get the idea across)
x = np.array([[0, 0, 1, 1],
              [1, np.nan, np.nan, np.nan],
              [2, np.nan, np.nan, np.nan],
              [3, 1, 0, 0],
              [4, np.nan, np.nan, np.nan],
              [5, 0, 1, 0],
              [6, np.nan, np.nan, np.nan],
              [7, np.nan, np.nan, np.nan],
              [8, np.nan, np.nan, np.nan],
              [9, 0, 0, 0]], dtype=float)


qidx = np.flatnonzero(~np.isnan(x[:, -1]))

for a, b in zip(qidx[:-1], qidx[1:]):
    ta, tb = x[a, 0], x[b, 0]
    qa, qb = x[a, 1:], x[b, 1:]
    xi = x[a+1:b]
    ratio = (xi[:, 0] - ta) / (tb - ta)

    # perform linear interpolation
    # should be replaced with quaternion interpolation
    xi[:, 1:] = qa + (qb - qa) * ratio[:, np.newaxis]
应该可以很容易地调整数组布局并插入一个四元数插值函数,该函数采用两个四元数(
qa
qb
和一个
比率
)。如果函数未矢量化(它不采用比率数组),则需要在
比率中的元素上循环

使用表格中的测试数据进行定时测试(此版本vs)

n = 2000000
k = 1500
x = np.concatenate([np.arange(n).reshape(-1, 1), np.zeros((n, 3)) + np.nan], axis=1)
x[0, 1:] = [0, 0, 0]
x[-1, 1:] = [0, 0, 0]
x[np.random.randint(n, size=k), 1:] = np.random.rand(k, 3)
结果:

       n/k     |   old   |  new   | speedup
---------------+---------+--------+------------
   20000/15    |    6 ms |   2 ms |  x3
  200000/150   |  313 ms |  23 ms |  x13
 2000000/1500  |   34 s  | 250 ms |  x136
20000000/15000 |    memory error

观察结果1的可能重复:您不需要搜索每个样本,因为许多样本将共享相同的上下四元数。观察结果2:可能最好改变方法,在两个给定四元数之间插值所有点-无需搜索。@kazemakase这两个好点。有没有办法创建大型逻辑m请求搜索?这是可行的,但掩码仍然存在速度问题。每个循环需要0.2秒,15000个x2点和2000万-15000个x1点。创建大型逻辑掩码仅需0.14秒。2*15000=50分钟计算时间您有大量数据,不要期望计算时间可以减少到零;)但是,您是对的,逻辑掩码有点浪费,因为它是在
x1
上全局构建的,而我们只需要几个局部元素。@Ianampbellmoore我已经更新了答案以避免掩码。它现在快得多,并且可以更好地扩展到更大的数组。但是,我不知道四元数插值的性能如何。我t肯定会比线性插值慢,可能会成为新的瓶颈。我实际上是通过从scipy.interpolate.interp1d中剥离代码来解决这个问题的,它使用np.searchsorted来查找在现有数组中应该放置新样本的位置。这让我在不到2秒内找到上下四元数解。我进一步优化了它通过剥离slerp函数并对其进行矢量化。但正是您的建议使我找到了此解决方案,所以我进行了投票。我将在稍后清理代码时发布我的代码
       n/k     |   old   |  new   | speedup
---------------+---------+--------+------------
   20000/15    |    6 ms |   2 ms |  x3
  200000/150   |  313 ms |  23 ms |  x13
 2000000/1500  |   34 s  | 250 ms |  x136
20000000/15000 |    memory error