i have a 3D-np.array s like this
s = np.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, 25, 26]]], dtype=float)
call (x, y, z) id coordinate of a element of array, how could i use numpy to caculate s[x, y, z] /= np.sum(s[:, :, z])
ex:
x, y, z = s.shape
s1 = s.copy()
for i in range(x):
for j in range(y):
for k in range(z):
s1[i, j, k] = s[i, j, k] / np.sum(s[:, :, k])
# I use s1 cause I scare s will change after every loop
# and np.sum(s[:,:,k]) is not a const
# pseudo-code example:
# s[0, 0, 1] = 1
# sum[:, :, 1] = 117 # sum of 2nd column
# then
# s[0,0,1] = 1/117
# repeat with x*y*z-1 point remain
i has try to use np.fromfunction
but if run too slow. my code ex:
def f(x, y, z):
result = s[x, y, z] / np.sum(s[:, :, z])
return result
s1 = np.fromfunction(np.vectorize(f), (a, b, c), dtype='int')
# a, b, c is shape of the array
Can I complete this with faster ways without for loop?
CodePudding user response:
What about
s/s.sum(axis=(0, 1), keepdims=True)
or equivalently
s/np.sum(s, axis=(0, 1), keepdims=True)
Argument axis
specifies the dimensions the sum
is performed along. keepdims
allows the result of the summation to keep its original dimensionality – 3
in the current case – which makes the division broadcast-gnostique.
CodePudding user response:
If you just want to divide all elements of the array by some value, it's enough to call the division without indexing the array.
test = np.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, 25, 26]]])
print(test/np.sum(test[:,:,1]))
Or if you want to embed it in a function:
def array_divide(inputArr):
return inputArr/np.sum(inputArr[:,:,1])