如何在Python 2.7中为外部指定级别深度(或轴)?

时间:2015-11-26 22:45:52

标签: arrays python-2.7 numpy

我正在尝试让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。

1 个答案:

答案 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)