2014-12-24 13 views
7

10 * 10 dizim var. Tüm katmanın toplamını bulmam lazım.Ndarray içinde sayı katmanı toplamı nasıl bulunur?

enter image description here

Bunu nasıl kolayca yapabilirsiniz: Aşağıdaki şekilde sorumu temizleyecektir?

+0

Eğer numpy kullanıyorsunuz garip için n diziler tarafından meydanda n için çalışır hatta n bir ara dizide (sadece kaba kuvvet indeksleme eğlence) dışarı? – Ffisegydd

+0

evet .. Numpy kullanıyorum – aerokite

cevap

2

bir çözüm: Bununla
>>> 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 

, sen örneğin kolayca olarak toplamları hesaplamak olabilir

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)) 

üretir:

[170, 122, 85, 62, 17] 
[67, 31, 7] 
+0

Aslında çok sayıda küçük ara diziler yaratıyorsunuz ...sum (a [i, i: n-i] + a [n-i-1, i: n-i]) ', numpy yeni bir' n-2 ​​* i 'öğe dizisini ayırır ve iki diliminizin elemansal toplamı ile doldurur. Bu, elbette, her bir dilimi bir araya getirmeden önce kendi başına toplayarak, ihmal edilemeyen bir hızlanma ile kaçınmak elbette kolaydır. Ayrıca standart kütüphanenin 'sum' yerine' np.sum 'kullanmalısınız. – Jaime

+0

@Jaime - haklısınız, elbette: Burada biraz dikkatsizdim. Önerilen kodu düzenledim. Teşekkürler. – xnx

0

Bir fikrim var. 1, 10 * 10 dizisinin toplamını bulun, sonra iç 9 * 9 dizisinin toplamını bulun. Daha sonra çıkarma, dış katmanın toplamının sonucudur.

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

Bir döngü tüm toplamı bulacaktır.

bunu yapmak için daha iyi bir yol yoktur olabilir ..

2

ortada bir (2n)*(2n) karenin toplamı nasıl biliyorsanız, o zaman çok kolaydır: o zaman, kare (2n)*(2n) toplamını almak içindeki (2n-2)*(2n-2) karesinin toplamını çıkartın; fark sınırında elemanlarının toplamı (yani, dış kare ancak iç değil):

import numpy 

# let x be a 10 * 10 array 
x = numpy.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], 
]) 

for i in xrange(1, 6): # loop with i = 1,...,5 
    # find the sum of the (2i)*(2i) square in the middle 
    a = numpy.sum(x[5-i:5+i, 5-i:5+i]) 

    # find the sum of the (2i-2)*(2i-2) square in the middle 
    b = numpy.sum(x[6-i:4+i, 6-i:4+i]) 

    # the difference gives the sum of the elements on the border 
    s = a - b 
    print s 
2

Aşağıdaki kod her bir katmanı hesaplar ve daha küçük tabakayı bundan çıkarır. Oldukça geneldir ve bu nedenle N * N boyutundaki herhangi bir dizi, N (sanırım) olduğu sürece ona geçirilebilmelidir. Dış olanlardan iç kareler çıkarılarak genel bir fikir muhtemelen en iyi yaklaşım olsa da çok iyi yapacağını sunulan uygulamaların performans hiçbiri istiyorsa onlar eklemeye devam beri

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] 
7

Sadece ... başka bir cevap eklemek için Aynı sayılar tekrar tekrar. Eğer herhangi bir dikdörtgen alt-dizenin alanını iki girdileri ekleyerek ve diğer iki çıkarılarak, örneğin hesaplayabilir bu yardımcı dizisi itibaren

>>> 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]]) 

: Bu hesaplama hızlandırmak için, ayrılmaz bir görüntü denir görüntü işlemede neyi kullanabilirsiniz

aynı elementlerin ile tekrarlanan toplamı olmadan Burada
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]