【发布时间】:2017-01-13 00:15:33
【问题描述】:
假设我有一个这样的矩阵
df = pd.DataFrame(randint(2,size=(3,9)))
df.values
array([[0, 1, 0, 1, 1, 1, 0, 1, 1],
[1, 0, 1, 1, 1, 1, 0, 0, 1],
[0, 0, 0, 1, 0, 0, 1, 1, 0]])
再次;本例中的每一行代表三个 3D 坐标,需要旋转,例如以下旋转矩阵:
array([[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00],
[ 0.00000000e+00, 1.00000000e+00, 0.00000000e+00],
[ -1.00000000e+00, 0.00000000e+00, 0.00000000e+00]])
为了尽可能高效地做到这一点(真正的问题有数百万个坐标顺便说一句),我有点困惑,我必须这样做:
首先应用df.reshape - 此示例中的每一行由三个 3D 坐标组成,如 [(x,y,z),(x,y,z),(x,y,z)]:
array([[0, 1, 0],
[1, 1, 1],
[0, 1, 1],
[1, 0, 1],
[1, 1, 1],
[0, 0, 1],
[0, 0, 0],
[1, 0, 0],
[1, 1, 0]])
那么为了得到rotate to convention,必须取u_new = R \dot u,这意味着上面的转置,这样我们就可以与旋转矩阵进行列(即坐标)乘法。
array([[0, 1, 0, 1, 1, 0, 0, 1, 1],
[1, 1, 1, 0, 1, 0, 0, 0, 1],
[0, 1, 1, 1, 1, 1, 0, 0, 0]])
然后我们可以做乘法:
pd.DataFrame(dot(rotmat,df)).values
array([[ 0.00e+00, 2.22e-16, 0.00e+00, 1.00e+00, 2.22e-16,
2.22e-16, 1.00e+00, 1.00e+00, 2.22e-16],
[ 1.00e+00, 0.00e+00, 1.00e+00, 1.00e+00, 1.00e+00,
1.00e+00, 0.00e+00, 0.00e+00, 1.00e+00],
[ 0.00e+00, -1.00e+00, 0.00e+00, -1.00e+00, -1.00e+00,
-1.00e+00, 2.22e-16, -1.00e+00, -1.00e+00]])
然后将整个过程反转,使其恢复原始形状,以用于其他目的。
肯定有更有效的方法来做到这一点(希望不会弄乱旋转矩阵)?
【问题讨论】:
-
我建议你使用 numpy 而不是 pandas 来处理几何变换,看看这个library。事实上,如果您正在寻找速度,请将数据传输到 GPU 并在那里进行转换
-
当然可以,但是我没有在 pandas 中进行转换,
dot来自 numpy,然后我将其存储在最后的 pandas 数据框中。 -
@BPL 写的是真的。由于您在询问效率,因此最好在 numpy 中执行所有操作。创建数据帧会产生开销;将所有数据保存在一个 numpy 数组中并避免推入和拉入其他数据结构的成本会更有效。
-
@James 这个我明白了,我不是在pandas里做操作;它是在 numpy 中完成的。我的库的性质是无论如何它都必须重新存储在 pandas 数据框中。
-
在
numpy中重塑和转置很快。矩阵乘积工具是dot、transdot、einsum和matmul(@)。对于简单的情况,dot是最快的,因为它使用了优化的库。
标签: python pandas numpy matrix