使用numpy可以获得三维空间中所有对象相对于一个对象的位置

2024-05-20 23:57:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我想得到numpy数组中向量对的所有排列之间的差异。在

在我的特定用例中,这些向量是对象列表的3D位置向量。在

因此,如果我有一个数组r = [r1, r2, r3],其中r1r2和{}是三维向量,我想要以下内容:

[[r1-r1 r1-r2 r1-r3]
 [r2-r1 r2-r2 r2-r3]
 [r3-r1 r3-r2 r3-r3]]

其中-op按元素顺序应用于向量。在

基本上,向量等价于:

^{pr2}$

然而,outer函数似乎在减法之前将我的向量数组展平,然后再对其进行整形。例如:

>>> vectors = np.arange(6).reshape(2, 3) # Two 3-dimensional vectors
>>> print(vectors)
[[0 1 2]
 [3 4 5]]

>>> results = np.subtract.outer(vectors, vectors)
>>> print(results.shape)
(2, 3, 2, 3)

我期待的结果是:

>>> print(result)
[[[ 0  0  0]
  [-3 -3 -3]]
 [[ 3  3  3]
  [ 0  0  0]]]

>>> print(result.shape)
(2, 2, 3)

不迭代上面的数组我能实现吗?在


Tags: numpynp数组差异result用例向量results
3条回答

简短回答:

对向量r进行“成对外减法”的(几乎)纯Python方法如下:

np.array(map(operator.sub, *zip(*product(r, r)))).reshape((2, 2, -1))

所以基本上可以使用product函数来获得所有可能的列表项对,取消zip得到两个独立的列表,并将它们map转换成减法operator。最后你可以像往常一样reshape。在

循序渐进:

下面是一个逐步示例,其中包含所有必需的库和中间结果的输出:

^{pr2}$

输出:

Vectors:
[[0 1 2]
 [3 4 5]]
Product:
[(array([0, 1, 2]), array([0, 1, 2])), (array([0, 1, 2]), array([3, 4, 5])), (array([3, 4, 5]), array([0, 1, 2])), (array([3, 4, 5]), array([3, 4, 5]))]
Zipped:
[(array([0, 1, 2]), array([0, 1, 2]), array([3, 4, 5]), array([3, 4, 5])), (array([0, 1, 2]), array([3, 4, 5]), array([0, 1, 2]), array([3, 4, 5]))]
Mapped:
[array([0, 0, 0]), array([-3, -3, -3]), array([3, 3, 3]), array([0, 0, 0])]
Reshaped:
[[[ 0  0  0]
  [-3 -3 -3]]

 [[ 3  3  3]
  [ 0  0  0]]]

(请注意,为了创建示例数组,我需要切换维度23

(在这里回答我自己的问题)

下面是一个使用Numpy的方法:

import numpy as np

N = 2
r = np.arange(N * 3).reshape(N, 3)

left = np.tile(r, N).reshape(N, N, 3)
right = np.transpose(left, axes=[1, 0, 2])

result = left - right
print result

这似乎适用于任何内部尺寸为3的2D数组,但我主要是通过反复试验来实现的,所以我不能百分之百确定。在

答案几乎总是broadcasting

>>> r = np.arange(6).reshape(2, 3)
>>> r[:, None] - r
array([[[ 0,  0,  0],
        [-3, -3, -3]],

       [[ 3,  3,  3],
        [ 0,  0,  0]]])

索引中的Nonenp.newaxis相同,并将大小为1的维度添加到数组的形状中。所以你要从一个形状为(2, 1, 3)的数组中减去一个形状为(2, 3)的数组,它通过广播转换成(1, 2, 3),最终结果就是你想要的(2, 2, 3)数组。虽然广播在概念上类似于使用np.tilenp.repeat,但它更有效,因为它避免创建原始数组的扩展副本。在

相关问题 更多 >