Python 沿二维数组中的函数求和

Python 沿二维数组中的函数求和,python,arrays,performance,numpy,sum,Python,Arrays,Performance,Numpy,Sum,是否可以在二维数组上放置一个线性函数,并对二维数组中与该函数重合的所有元素求和?例如,我会有一个二维数组,比如说(400500)。现在在某个地方,我会重叠一个线性函数,它从2D数组的底部向顶部延伸。我现在只想求与线性线重叠的2D数组元素的和 有没有一种快速的方法可以只求二维数组中与直线重合的元素的和?我已经能够通过在for循环中使用for循环来实现这一点。然而,这已经需要一些时间。特别是如果我想开始将此技巧应用于更大的阵列。这在某种程度上取决于您如何准确定义该行,以及哪些阵列位置被视为“在”该行

是否可以在二维数组上放置一个线性函数,并对二维数组中与该函数重合的所有元素求和?例如,我会有一个二维数组,比如说(400500)。现在在某个地方,我会重叠一个线性函数,它从2D数组的底部向顶部延伸。我现在只想求与线性线重叠的2D数组元素的和


有没有一种快速的方法可以只求二维数组中与直线重合的元素的和?我已经能够通过在for循环中使用for循环来实现这一点。然而,这已经需要一些时间。特别是如果我想开始将此技巧应用于更大的阵列。

这在某种程度上取决于您如何准确定义该行,以及哪些阵列位置被视为“在”该行上。但一个简单的方法是使用布尔掩码。使用
numpy.mgrid
,可以很容易地沿一条线定义掩码:

>>> grid = numpy.mgrid[0:5,0:5]
>>> grid
array([[[0, 0, 0, 0, 0],
        [1, 1, 1, 1, 1],
        [2, 2, 2, 2, 2],
        [3, 3, 3, 3, 3],
        [4, 4, 4, 4, 4]],

       [[0, 1, 2, 3, 4],
        [0, 1, 2, 3, 4],
        [0, 1, 2, 3, 4],
        [0, 1, 2, 3, 4],
        [0, 1, 2, 3, 4]]])
如您所见,这是一个由x和y值组成的网格,然后您可以将它们关联到一个方程中,如下所示:

>>> grid[0] == 2 * grid[1]
array([[ True, False, False, False, False],
       [False, False, False, False, False],
       [False,  True, False, False, False],
       [False, False, False, False, False],
       [False, False,  True, False, False]], dtype=bool)
>>> grid[0] == grid[1]
array([[ True, False, False, False, False],
       [False,  True, False, False, False],
       [False, False,  True, False, False],
       [False, False, False,  True, False],
       [False, False, False, False,  True]], dtype=bool)
>>> grid[0] == grid[1] / 2
array([[ True,  True, False, False, False],
       [False, False,  True,  True, False],
       [False, False, False, False,  True],
       [False, False, False, False, False],
       [False, False, False, False, False]], dtype=bool)
请注意,您可能需要仔细思考为什么
grid[0]==grid[1]/2
会给出一条“连续”线,而
grid[0]==2*grid[1]
不会,并准确地找出您想要的行为。(使用稍微复杂的方程式,可以指定允许创建不同厚度线的公差值。)

然后可以使用生成的掩码进行求和:

>>> a = numpy.arange(25).reshape(5, 5)
>>> a
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24]])
>>> a[grid[0] == grid[1] / 2]
array([ 0,  1,  7,  8, 14])
>>> a[grid[0] == grid[1] / 2].sum()
30
这比嵌套for循环快得多,因为
numpy
非常快。但它仍然执行相同数量的操作

另一种方法可能是直接从
x
值计算
y
值。这样做的好处是,它不必执行那么多操作,因此对于非常大的阵列,速度会更快:

>>> x = numpy.arange(5)
>>> y = x * 2
>>> valid_indices = (x < 5) & (y < 5)
>>> a[x[valid_indices], y[valid_indices]]
array([ 0,  7, 14])
同样,正如你所看到的,这条线中有一些间隙;如果您想消除这些间隙,您必须通过“拉伸”x或y值来稍微改变它。这里有一个函数,它使用一个简单的斜率截距规范来实现这一点。您仍然需要为
0
和无限坡度添加特殊套管,但这做了大量必要的工作,并在我测试的所有情况下生成了一条漂亮、平滑的线条:

def linear_index(slope, intercept, x_range, y_range):
    if numpy.abs(slope) < 1:
        intercept = intercept / slope
        slope = 1 / slope
        y, x = linear_index(slope, intercept, y_range, x_range)
        return x, y

    x_min, x_max = x_range
    y_min, y_max = y_range
    x = numpy.linspace(x_min, x_max - 1, (x_max - x_min - 1) * slope + 1)
    y = x * slope + intercept
    print x, y
    valid_indices = (y >= y_min) & (y < y_max)
    return x[valid_indices].astype(int), y[valid_indices].astype(int)
def线性指数(斜率、截距、x范围、y范围):
如果单位绝对值(斜率)<1:
截距=截距/坡度
坡度=1/坡度
y、 x=线性指数(斜率、截距、y范围、x范围)
返回x,y
x_最小值,x_最大值=x_范围
y_最小值,y_最大值=y_范围
x=numpy.linspace(x_最小,x_最大-1,(x_最大-x_最小-1)*斜率+1)
y=x*斜率+截距
打印x,y
有效指数=(y>=y\U最小值)和(y

如果充分理解了,将
(r,θ)
对转换为斜率截距形式应该不会有任何问题。不过,如果您需要更粗的线条,这可能不是最好的方法

你能提供你想要的输入和输出的样本吗?可能吧!发布一个简化的2D数组示例、函数和预期输出。目前的问题有点模糊(什么是“线性线”)?我想你要求的是类似于离散线积分的东西,对吗?二维数组的最大形式可以定义为:
numpy.arange((1002*1004))。重塑(10021004)
。线性线由
x cos(phi)+y sin(phi)
定义,这里phi的顺序是pi/3。什么是
x
y
?它们与2d阵列的关系是什么?我想使用的线性函数取决于变化的角度。线性线是由x cos(phi)+y sin(phi)
@user2776885定义的,现在我更困惑了
x cos(phi)+y sin(phi)
是x和y的二维函数——它不是一条直线。它是用来表示直线(y=ax+b)的霍夫变换。然而,Hough变换考虑的不是直线的特征作为图像点(x1,y1),(x2,y2),而是斜率参数a和截距参数b。@user2776885,它不完全是Hough变换。去看看维基百科页面。这表明你提供的公式是不完整的。如果你理解了这一页,我的回答应该很容易适应你的问题。
def linear_index(slope, intercept, x_range, y_range):
    if numpy.abs(slope) < 1:
        intercept = intercept / slope
        slope = 1 / slope
        y, x = linear_index(slope, intercept, y_range, x_range)
        return x, y

    x_min, x_max = x_range
    y_min, y_max = y_range
    x = numpy.linspace(x_min, x_max - 1, (x_max - x_min - 1) * slope + 1)
    y = x * slope + intercept
    print x, y
    valid_indices = (y >= y_min) & (y < y_max)
    return x[valid_indices].astype(int), y[valid_indices].astype(int)