我正在尝试在Scipy / Numpy中创建一个二维数组,其中每个值代表距离中心的欧氏距离。它应该具有与三维数组的前两个维度相同的形状(图像,通过 scipy.misc.fromimage 创建)。
这是一种有效的方法:
def get_distance_1(y, x):
mid_x, mid_y = (scipy.array(image_array.shape[:2]) - 1) / float(2)
return ((y - mid_y) ** 2 + (x - mid_x) ** 2) ** 0.5
distances = scipy.fromfunction(get_distance_1, image_array.shape[:2])
这种方法相当快,但我对Scipy很新,并且想知道是否有一种更优雅,惯用的方法来做同样的事情。我找到了 scipy.spatial.distance.cdist 函数,这似乎很有希望,但我对如何使它适应这个问题感到茫然。
def get_distance_2(y, x):
mid = ... # needs to be a array of the shape (rows, cols, 2)?
return scipy.spatial.distance.cdist(scipy.dstack((y, x)), mid)
只是为了澄清,我正在寻找的是这样的(对于6 x 6阵列)
[[ 3.53553391 2.91547595 2.54950976 2.54950976 2.91547595 3.53553391]
[ 2.91547595 2.12132034 1.58113883 1.58113883 2.12132034 2.91547595]
[ 2.54950976 1.58113883 0.70710678 0.70710678 1.58113883 2.54950976]
[ 2.54950976 1.58113883 0.70710678 0.70710678 1.58113883 2.54950976]
[ 2.91547595 2.12132034 1.58113883 1.58113883 2.12132034 2.91547595]
[ 3.53553391 2.91547595 2.54950976 2.54950976 2.91547595 3.53553391]]
答案 0 :(得分:2)
我会说惯用的方法是对它进行矢量化。
原始函数get_distance_1
可能设计时考虑了标量参数(单个数字),但实际上也适用于Numpy数组,无需修改。这意味着您可以使用x和y索引传递数组,它将提供所需的结果。
import numpy as np
m, n = image_array.shape[:2]
x_inds = np.arange(m)
y_inds = np.arange(n)
distances = get_distance_1(x_inds[:,None], y_inds)
使用None
建立索引(相当于使用np.newaxis
建立索引)将轴添加到一维向量并有效地转置它。这是参与broadcasting的必要条件。
稍微短一些:
x_inds, y_inds = np.ogrid[:m, :n]
distances = get_distance_1(x_inds, y_inds)
请注意,您必须撤消x
中y
和get_distance_1
的定义,才能获得与中心相关的距离:
def get_distance_1(x, y):
mid_x, mid_y = (scipy.array(image_array.shape[:2]) - 1) / float(2)
return ((y - mid_y) ** 2 + (x - mid_x) ** 2) ** 0.5
答案 1 :(得分:1)
cdist
是正确的功能。给定两组积分X
和Y
,它会为x
和{{1}中的所有y
返回x
和X
之间的距离在y
中。在这种情况下,其中一组是单身:
Y
这是一个二维数组,因此您可能希望>>> X = np.random.randn(10, 3) # random 3-d points
>>> center = np.random.randn(3)
>>> scipy.spatial.distance.cdist(X, np.atleast_2d(center)) # both must be 2-d
array([[ 2.72130005],
[ 1.62765189],
[ 1.14245608],
[ 2.55279445],
[ 2.43727709],
[ 3.20647709],
[ 1.65028127],
[ 0.79044422],
[ 1.8180881 ],
[ 2.38094952]])
:
ravel