Home > Software design >  caculate 3-D array numpy value without loops base on exist 3-D array numpy
caculate 3-D array numpy value without loops base on exist 3-D array numpy

Time:12-03

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 dimensionality3 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])
  • Related