如何在ndarray中找到数字层的总和

时间:2014-12-24 15:40:47

标签: python numpy multidimensional-array

我有一个10 * 10阵列。我需要找到所有图层的总和。下图将清楚我的问题:

enter image description here

我怎样才能轻松完成这项工作?

5 个答案:

答案 0 :(得分:7)

只是为了添加另一个答案......虽然从外部方法中减去内部方块的一般想法可能是最好的方法,但如果你想要性能,所提出的实现都不会做得太好,因为他们不断添加相同的数字并结束。为了加快计算速度,您可以使用图像处理中的内容称为整数图像:

>>> int_arr = np.cumsum(np.cumsum(arr, axis=0), axis=1)
>>> int_arr
array([[  8,   8,  15,  19,  22,  22,  22,  29,  35,  44],
       [ 16,  17,  24,  34,  40,  44,  46,  54,  64,  79],
       [ 24,  30,  46,  62,  76,  80,  82,  91, 104, 119],
       [ 27,  35,  59,  84, 103, 115, 123, 137, 156, 178],
       [ 33,  48,  77, 103, 123, 135, 148, 163, 191, 213],
       [ 41,  65,  98, 129, 158, 177, 190, 205, 233, 259],
       [ 48,  81, 120, 158, 191, 217, 235, 251, 286, 316],
       [ 54,  95, 136, 180, 214, 249, 275, 296, 333, 364],
       [ 63, 105, 147, 194, 235, 276, 310, 331, 376, 414],
       [ 65, 115, 163, 213, 260, 306, 340, 364, 410, 456]])

从这个辅助数组中,你可以计算任意矩形子阵列的面积,增加两个条目并减去另外两个,例如:

>>> np.sum(arr[1:-1, 1:-1])
286
>>> int_arr[-2,-2] + int_arr[0, 0] - int_arr[-2, 0] - int_arr[0, -2]
286

有了这个,您可以轻松地计算您的总和,例如:

sums = [int_arr[-1, -1]]
top = 0
bot = len(arr) - 2
while top < bot:
    new_sum = (int_arr[bot, bot] + int_arr[top, top] -
               int_arr[top, bot] - int_arr[bot, top])
    sums[-1] -= new_sum
    sums.append(new_sum)
    top += 1
    bot -= 1

>>> sums
[170, 122, 85, 62, 17]

答案 1 :(得分:2)

如果你知道如何在中间得到(2n)*(2n)平方的总和,那么很容易:取(2n)*(2n)平方的和,然后减去{{1}的总和里面的广场;差异是边界上元素的总和(即,在外部广场而不是内部):

(2n-2)*(2n-2)
  

17
  62个
  85个
  122个
  170

答案 2 :(得分:2)

下面的代码计算每一层,然后从中减去较小的层。它非常通用,因此任何大小为N * N的数组都应该能够传递给它,只要N是偶数(我认为)。

import numpy as np

arr = np.array([[8, 0, 7, 4, 3, 0, 0, 7, 6, 9],
                [8, 1, 0, 6, 3, 4, 2, 1, 4, 6],
                [8, 5, 9, 6, 8, 0, 0, 1, 3, 0],
                [3, 2, 8, 9, 5, 8, 6, 5, 6, 7],
                [6, 7, 5, 1, 1, 0, 5, 1, 9, 0],
                [8, 9, 4, 5, 9, 7, 0, 0, 0, 4],
                [7, 9, 6, 7, 4, 7, 5, 1, 7, 4],
                [6, 8, 2, 6, 1, 9, 8, 5, 2, 1],
                [9, 1, 1, 3, 7, 6, 8, 0, 8, 7],
                [2, 8, 6, 3, 6, 5, 0, 3, 1, 8]])

N = len(arr)

def sum_layer(arr, M, N=N):
    """Function to return the sum of a layer."""
    return arr[M:N-M, M:N-M].sum()

# Each of the layers.
layers = [sum_layer(arr, i) for i in range(N - N//2)]

# Subtract the smaller areas from the larger, to get the margins.
result = [layers[i] - layers[i+1] for i in range(N//2 - 1)]

# Need to add the final, smallest layer on.
result.append(layers[-1])

print(result)
# [170, 122, 85, 62, 17]

答案 3 :(得分:2)

这是一个没有重复求和相同元素且没有中间数组(只是蛮力索引乐趣)的解决方案,它适用于n个方格的n数组,用于奇数或偶数{{1} }:

n

产地:

import numpy as np

def sum_shells(a):
    n = len(a)
    no2 = n // 2
    shell_sums = []
    for i in range(no2):
        shell_sums.append(np.sum(a[i,i:n-i]) + np.sum(a[n-i-1,i:n-i]) +
                          np.sum(a[i+1:n-i-1,i]) + np.sum(a[i+1:n-i-1,n-i-1]))
    if n % 2:
        shell_sums.append(a[no2, no2])
    return shell_sums

a = np.array([
  [8, 0, 7, 4, 3, 0, 0, 7, 6, 9],
  [8, 1, 0, 6, 3, 4, 2, 1, 4, 6],
  [8, 5, 9, 6, 8, 0, 0, 1, 3, 0],
  [3, 2, 8, 9, 5, 8, 6, 5, 6, 7],
  [6, 7, 5, 1, 1, 0, 5, 1, 9, 0],
  [8, 9, 4, 5, 9, 7, 0, 0, 0, 4],
  [7, 9, 6, 7, 4, 7, 5, 1, 7, 4],
  [6, 8, 2, 6, 1, 9, 8, 5, 2, 1],
  [9, 1, 1, 3, 7, 6, 8, 0, 8, 7],
  [2, 8, 6, 3, 6, 5, 0, 3, 1, 8] ])

b = np.array([[9, 5, 8, 6, 5],
              [1, 1, 0, 5, 1],
              [5, 9, 7, 0, 0],
              [7, 4, 7, 5, 1],
              [9, 5, 0, 2, 3] ])
print(sum_shells(a))
print(sum_shells(b))

答案 4 :(得分:0)

我有个主意。 1找到整个10 * 10数组的总和,然后找到内部9 * 9数组的总和。然后减法是外层总和的结果。

for i in range(len(A)/2):
    B = A[1:-1, 1:-1]
    print sum(A)-sum(B)
    A = B

循环将找到所有总和。

可能有更好的方法来做到这一点..