Ho un array 10 * 10. Ho bisogno di trovare la somma di tutto il livello. figura seguente cancellerà la mia domanda:Come trovare la somma del layer numero in ndarray
Come posso fare questo facilmente?
Ho un array 10 * 10. Ho bisogno di trovare la somma di tutto il livello. figura seguente cancellerà la mia domanda:Come trovare la somma del layer numero in ndarray
Come posso fare questo facilmente?
Ecco una soluzione senza ripetuto sommatoria degli stessi elementi e con fuori una serie intermedia (solo forza bruta indicizzazione divertente) che lavora per piazza n
da n
array per pari o dispari 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))
produce:
[170, 122, 85, 62, 17]
[67, 31, 7]
In realtà stai creando molti piccoli array intermedi ... Quando fai ad es.'sum (a [i, i: n-i] + a [n-i-1, i: n-i])', numpy alloca un nuovo array di elementi 'n-2 * i' e lo riempie con la somma elementale delle due fette. Questo è ovviamente facile da evitare, con una velocità probabilmente non trascurabile, sommando ogni fetta da sola prima di aggiungerli insieme. Dovresti usare anche 'np.sum' invece della' somma' della libreria standard. – Jaime
@Jaime - hai ragione, certo: ero un po 'incurante qui. Ho modificato il codice suggerito. Grazie. – xnx
Ho un'idea. 1 ° trova la somma dell'intero array 10 * 10, quindi trova la somma dell'array 9 * 9 interno. Quindi la sottrazione è il risultato della somma dello strato esterno.
for i in range(len(A)/2):
B = A[1:-1, 1:-1]
print sum(A)-sum(B)
A = B
Un ciclo troverà tutta la somma.
può essere c'è modo migliore per fare questo ..
Se si sa come ottenere la somma di un quadrato (2n)*(2n)
nel mezzo, allora è molto facile: prendere la somma del (2n)*(2n)
piazza, poi sottrarre la somma del quadrato (2n-2)*(2n-2)
al suo interno; la differenza è la somma degli elementi sul bordo (cioè, sono in piazza esterno, ma non l'interno):
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
Il codice seguente calcola ogni livello e quindi sottrae il livello più piccolo da esso. È abbastanza generale e quindi qualsiasi array di dimensioni N * N dovrebbe poter essere passato ad esso, purché lo N
sia pari (credo).
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]
Giusto per aggiungere un'altra risposta ... Mentre l'idea generale di sottrarre piazze interne da quelle esterne è probabilmente l'approccio migliore, se si voleva prestazioni nessuna delle implementazioni presentate avrebbe fatto troppo bene, dal momento che continuare ad aggiungere gli stessi numeri più e più volte. Per accelerare questo calcolo up, è possibile utilizzare quello in elaborazione delle immagini viene chiamato un'immagine integrale:
>>> 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]])
Da questo array helper è possibile calcolare l'area di ogni sottomatrice rettangolare aggiungendo due voci e sottraendo altri due, ad esempio:
>>> 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
con questo, si potrebbe calcolare le vostre somme facilmente come, ad esempio:
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]
Si sta utilizzando numpy? – Ffisegydd
sì .. Sto usando numpy – aerokite