我有一个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。
答案 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]
应该可以很容易地调整阵列布局并插入四元数插值函数,该函数需要两个四元数(qa
和qb
以及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