我正在尝试让Python 2.7执行此操作(我在Mathematica中提供了示例,因为我知道如何在那里执行)。基本上我有一个很多3D矢量的列表,即一个数组n * 3(这里我使用n = 4,但在我的问题中,n可以是几百或更多;我正在寻找速度,比'循环'更快的东西) :
Input:
vecs = {{ax, ay, az}, {bx, by, bz}, {cx, cy, cz}, {dx, dy, dz}};
我想形成这两个向量之间所有差异的数组。这将是一个数组n * n * 3。关键是告诉外部在一定程度上停止将事物分解为组件:
Input:
diff = Outer[Subtract, vecs, vecs, 1]
Output:
{{{0, 0, 0},
{ax - bx, ay - by, az - bz},
{ax - cx, ay - cy, az - cz},
{ax - dx, ay - dy, az - dz}},
{{-ax + bx, -ay + by, -az + bz},
{0, 0, 0},
{bx - cx, by - cy, bz - cz},
{bx - dx, by - dy, bz - dz}},
{{-ax + cx, -ay + cy, -az + cz},
{-bx + cx, -by + cy, -bz + cz},
{0, 0, 0},
{cx - dx, cy - dy, cz - dz}},
{{-ax + dx, -ay + dy, -az + dz},
{-bx + dx, -by + dy, -bz + dz},
{-cx + dx, -cy + dy, -cz + dz},
{0, 0, 0}}}
基本上,我不想减去所有可能的组合,只有x组件的x组件等。这在物理学中很常见,当我阅读numpy数组函数的文档时,我得到的印象是我在凝视在答案中,但我无法看到如何在Python中实现Mathematica Outer命令中的'1'。如果我不使用Mathematica中的最后一个'1',那么我会得到一个更大的数组,这就是我现在用Python获得的数据。
提前致谢,
OL。
答案 0 :(得分:0)
似乎您可以通过将vecs
扩展到3D数组来使用broadcasting
,这样第二个轴就是单个维度,因此当从中减去原始的2D版本时,您将拥有预期的3D形状n x n x 3
数组。这种高效的矢量化解决方案看起来像这样 -
vecs[:,None,:] - vecs
验证输出 -
In [318]: vecs
Out[318]:
array([[1, 4, 8], # {ax, ay, az}
[7, 8, 7], # {bx, by, bz}
[1, 4, 8], # {cx, cy, cz}
[4, 3, 1]]) # {dx, dy, dz}
In [319]: vecs.shape
Out[319]: (4, 3)
In [320]: vecs[:,None,:] - vecs
Out[320]:
array([[[ 0, 0, 0], # {0, 0, 0}
[-6, -4, 1], # {ax - bx, ay - by, az - bz}
[ 0, 0, 0],
[-3, 1, 7]],
[[ 6, 4, -1],
[ 0, 0, 0],
[ 6, 4, -1],
[ 3, 5, 6]],
[[ 0, 0, 0],
[-6, -4, 1], # {-bx + cx, -by + cy, -bz + cz}
[ 0, 0, 0],
[-3, 1, 7]],
[[ 3, -1, -7],
[-3, -5, -6],
[ 3, -1, -7], # {-cx + dx, -cy + dy, -cz + dz},
[ 0, 0, 0]]]) # {0, 0, 0}
In [321]: (vecs[:,None,:] - vecs).shape
Out[321]: (4, 4, 3)