"outer" in python 类似于 Mathematica
"outer" in python similar to Mathematica
我有一些粒子的二维位置 (x,y) 数组。在 Mathematica 中,我可以使用
Outer[Subtract, pos, pos, 1]
如果 pos
是形状为 (n,2)
的数组,其中 n
是粒子数,则上述 Mathematia 代码的结果是 n x n x 2
数组,每个 [i,j]该矩阵的元素是 (x_i - x_j, y_i - y_j)
运算的结果。
例如
pos = {{x1, y1}, {x2, y2}, {x3, y3}};
Outer[Subtract, pos, pos, 1]
给予
{
{{0, 0}, {x1 - x2, y1 - y2}, {x1 - x3, y1 - y3}}
,
{{-x1 + x2, -y1 + y2}, {0, 0}, {x2 - x3, y2 - y3}}
,
{{-x1 + x3, -y1 + y3}, {-x2 + x3, -y2 + y3}, {0, 0}}
}
这是一个 3x3x2 数组。但是,在 python 中我无法得到类似的结果:
import numpy as np
pos = [[1, 2], [5, 6], [8, 9]]
print (np.subtract.outer(pos, pos).shape)
给出(3, 2, 3, 2)
,而np.subtract.outer(pos, pos)
是
array([[[[ 0, -1],
[-4, -5],
[-7, -8]],
[[ 1, 0],
[-3, -4],
[-6, -7]]],
[[[ 4, 3],
[ 0, -1],
[-3, -4]],
[[ 5, 4],
[ 1, 0],
[-2, -3]]],
[[[ 7, 6],
[ 3, 2],
[ 0, -1]],
[[ 8, 7],
[ 4, 3],
[ 1, 0]]]])
而对于类似的值,Mathemtica 代码给出了我所需要的,即
{
{{0, 0}, {-4, -4}, {-7, -7}}
,
{{4, 4}, {0, 0}, {-3, -3}}
,
{{7, 7}, {3, 3}, {0, 0}}
}
numpy.ufunc.outer(a,b)
将使用 a
中的一个元素和 b
中的另一个元素计算每个可能的组合。一种选择是分别计算 x 和 y 坐标,然后重新合并 result
:
pos = np.array([[1, 2], [5, 7], [8, 13]])
dx = np.subtract.outer(pos[:,0],pos[:,0])
dy = np.subtract.outer(pos[:,1],pos[:,1])
result=np.transpose([dx,dy], axes=(1,2,0))
(我更改了 pos
中的值,使结果不那么对称。)
编辑:与通过对整个数组执行 subtract.outer
然后在之后使用 squeeze
来计算和存储无用的 x_i-y_j 相比,此解决方案对于大型数组更有效。
您正在寻找:
pos = np.array(pos)
pos[:,None]-pos
您也可以通过以下方式实现同样的效果:
np.squeeze([i-pos for i in pos])
编辑:
为了归一化,你可以这样做:
ss = np.linalg.norm(pos_diff,axis = 2,keepdims = True)
ss[ss==0] = 1
pos_diff/ss
我有一些粒子的二维位置 (x,y) 数组。在 Mathematica 中,我可以使用
Outer[Subtract, pos, pos, 1]
如果 pos
是形状为 (n,2)
的数组,其中 n
是粒子数,则上述 Mathematia 代码的结果是 n x n x 2
数组,每个 [i,j]该矩阵的元素是 (x_i - x_j, y_i - y_j)
运算的结果。
例如
pos = {{x1, y1}, {x2, y2}, {x3, y3}};
Outer[Subtract, pos, pos, 1]
给予
{
{{0, 0}, {x1 - x2, y1 - y2}, {x1 - x3, y1 - y3}}
,
{{-x1 + x2, -y1 + y2}, {0, 0}, {x2 - x3, y2 - y3}}
,
{{-x1 + x3, -y1 + y3}, {-x2 + x3, -y2 + y3}, {0, 0}}
}
这是一个 3x3x2 数组。但是,在 python 中我无法得到类似的结果:
import numpy as np
pos = [[1, 2], [5, 6], [8, 9]]
print (np.subtract.outer(pos, pos).shape)
给出(3, 2, 3, 2)
,而np.subtract.outer(pos, pos)
是
array([[[[ 0, -1],
[-4, -5],
[-7, -8]],
[[ 1, 0],
[-3, -4],
[-6, -7]]],
[[[ 4, 3],
[ 0, -1],
[-3, -4]],
[[ 5, 4],
[ 1, 0],
[-2, -3]]],
[[[ 7, 6],
[ 3, 2],
[ 0, -1]],
[[ 8, 7],
[ 4, 3],
[ 1, 0]]]])
而对于类似的值,Mathemtica 代码给出了我所需要的,即
{
{{0, 0}, {-4, -4}, {-7, -7}}
,
{{4, 4}, {0, 0}, {-3, -3}}
,
{{7, 7}, {3, 3}, {0, 0}}
}
numpy.ufunc.outer(a,b)
将使用 a
中的一个元素和 b
中的另一个元素计算每个可能的组合。一种选择是分别计算 x 和 y 坐标,然后重新合并 result
:
pos = np.array([[1, 2], [5, 7], [8, 13]])
dx = np.subtract.outer(pos[:,0],pos[:,0])
dy = np.subtract.outer(pos[:,1],pos[:,1])
result=np.transpose([dx,dy], axes=(1,2,0))
(我更改了 pos
中的值,使结果不那么对称。)
编辑:与通过对整个数组执行 subtract.outer
然后在之后使用 squeeze
来计算和存储无用的 x_i-y_j 相比,此解决方案对于大型数组更有效。
您正在寻找:
pos = np.array(pos)
pos[:,None]-pos
您也可以通过以下方式实现同样的效果:
np.squeeze([i-pos for i in pos])
编辑:
为了归一化,你可以这样做:
ss = np.linalg.norm(pos_diff,axis = 2,keepdims = True)
ss[ss==0] = 1
pos_diff/ss