计算向量中所有条目组合之间的差异
calculate difference between all combinations of entries in a vector
我有一个 z 值的 numpy 一维数组,我想计算所有条目组合之间的差异,输出为方阵。
我知道如何使用 cdist 将其计算为点的所有组合之间的距离,但这并没有给我符号:
例如,如果我的 z 向量是 [1,5,8]
import numpy as np
from scipy.spatial.distance import cdist
z=np.array([1, 5, 8])
z2=np.column_stack((z,np.zeros(3)))
cdist(z2,z2)
给我:
array([[0., 4., 7.],
[4., 0., 3.],
[7., 3., 0.]])
但我想有迹象给我:
array([[0., 4., 7.],
[-4., 0., 3.],
[-7., -3., 0.]])
我考虑过使用 np.tril_indices 来翻转下三角的符号,但这行不通,因为我需要以一致的方式区分这些对以进行操作(即如果我在两个或更多向量上执行此操作,则总是以相同的顺序比较这些对),而通过翻转符号,我将始终在右上角和左下角有负差异。
我已经知道我可以使用嵌套迭代器得到我想要的答案,尽管我不确定它对于非常大的数组是否最有效
np.array([j-i for i in z for j in z]).reshape(len(z),len(z))
输出:
array([[ 0, 4, 7],
[-4, 0, 3],
[-7, -3, 0]])
编辑:所以其他两个解决方案确实快了大约 50 倍:
python3 -m timeit -s "import numpy as np" -s "z=np.random.uniform(size=5000)" "z-z.reshape(-1,1)"
2 loops, best of 5: 119 msec per loop
python3 -m timeit -s "import numpy as np" -s "z=np.random.uniform(size=5000)" "np.subtract.outer(z, z)"
2 loops, best of 5: 118 msec per loop
python3 -m timeit -s "import numpy as np" -s "z=np.random.uniform(size=5000)" "np.array([j-i for i in z for j in z]).reshape(len(z),len(z))"
1 loop, best of 5: 5.18 sec per loop
使用 numpy 数组广播的简单单行解决方案。
import numpy as np
z = np.array([1, 5, 8])
# Simple one line solution
z - z.reshape(-1,1)
输出:
array([[ 0, 4, 7],
[-4, 0, 3],
[-7, -3, 0]])
In [29]: z = np.array([1, 5, 8])
In [30]: -np.subtract.outer(z, z)
Out[30]:
array([[ 0, 4, 7],
[-4, 0, 3],
[-7, -3, 0]])
(如果您不关心符号约定,请去掉减号。)
我有一个 z 值的 numpy 一维数组,我想计算所有条目组合之间的差异,输出为方阵。
我知道如何使用 cdist 将其计算为点的所有组合之间的距离,但这并没有给我符号:
例如,如果我的 z 向量是 [1,5,8]
import numpy as np
from scipy.spatial.distance import cdist
z=np.array([1, 5, 8])
z2=np.column_stack((z,np.zeros(3)))
cdist(z2,z2)
给我:
array([[0., 4., 7.],
[4., 0., 3.],
[7., 3., 0.]])
但我想有迹象给我:
array([[0., 4., 7.],
[-4., 0., 3.],
[-7., -3., 0.]])
我考虑过使用 np.tril_indices 来翻转下三角的符号,但这行不通,因为我需要以一致的方式区分这些对以进行操作(即如果我在两个或更多向量上执行此操作,则总是以相同的顺序比较这些对),而通过翻转符号,我将始终在右上角和左下角有负差异。
我已经知道我可以使用嵌套迭代器得到我想要的答案,尽管我不确定它对于非常大的数组是否最有效
np.array([j-i for i in z for j in z]).reshape(len(z),len(z))
输出:
array([[ 0, 4, 7],
[-4, 0, 3],
[-7, -3, 0]])
编辑:所以其他两个解决方案确实快了大约 50 倍:
python3 -m timeit -s "import numpy as np" -s "z=np.random.uniform(size=5000)" "z-z.reshape(-1,1)"
2 loops, best of 5: 119 msec per loop
python3 -m timeit -s "import numpy as np" -s "z=np.random.uniform(size=5000)" "np.subtract.outer(z, z)"
2 loops, best of 5: 118 msec per loop
python3 -m timeit -s "import numpy as np" -s "z=np.random.uniform(size=5000)" "np.array([j-i for i in z for j in z]).reshape(len(z),len(z))"
1 loop, best of 5: 5.18 sec per loop
使用 numpy 数组广播的简单单行解决方案。
import numpy as np
z = np.array([1, 5, 8])
# Simple one line solution
z - z.reshape(-1,1)
输出:
array([[ 0, 4, 7],
[-4, 0, 3],
[-7, -3, 0]])
In [29]: z = np.array([1, 5, 8])
In [30]: -np.subtract.outer(z, z)
Out[30]:
array([[ 0, 4, 7],
[-4, 0, 3],
[-7, -3, 0]])
(如果您不关心符号约定,请去掉减号。)