大型numpy阵列的球面插值

时间:2018-01-31 06:20:25

标签: python numpy interpolation nan

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

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

有两种不同的样本,一种包含[time,X,Y,Z]数据,另一种包含[time,QW,QX,QY,QZ]。由于数组是同构的,因此第一种类型的样本看起来像[time,X,Y,Z,nan,nan,nan,nan],第二种类型的样本看起来像[time,nan,nan,nan,QW,QX,QY,QZ]。还有更多类型[time,X,Y,Z,nan,nan,nan,nan]的样本。阵列中只有20,000个类型为[time,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值?

pyquaternion interpolate函数接受参数(quaternion1,quaternion2,ratio)

其中比率是(TimeOfPoint-TimeQuaternion1)/(TimeQuaternion2-TimeQuaternion1)

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

对于示例点1000000,我尝试过:

data.shape =(20000000,8)

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

quat2=Quaternion(data[np.where((data[1000000,0]<=data[:,0]) & (~np.isnan(data[:,4])))[0][0],4:8])

这样可行,但每个样本需要2秒钟。

我正在寻找一种更快的方法来找到每个x,y,z点的上下四元数观察,以便SLERP。

1 个答案:

答案 0 :(得分:1)

我通常不使用四元数,所以我没有任何可用的实现。但是,由于问题似乎是如何找到插值点,这与四元数没有直接关系。

这种方法迭代可用的观察对并插入位于其间的所有样本:

# 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]

应该可以很容易地调整阵列布局并插入四元数插值函数,该函数需要两个四元数(qaqb以及ratio)。如果函数没有矢量化(它不需要一系列比率),则需要遍历ratio中的元素。

使用表格

的测试数据进行计时测试(此版本与previous version
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