Home > Software design >  how to find average of a section in an array using numpy
how to find average of a section in an array using numpy

Time:11-11

import numpy as np

temp_array = np.array(
  [[33.5, 35.3, 33.6, 33.6, 33.5, 33.9, 32.3, 33.2, 53.8, 54.6, 53.4, 54.2],
   [33.1, 34.2, 34.1, 34.3, 34.7, 31.3, 32.3, 33.4, 57.5, 55. , 53.5, 56.1],
   [35.3, 35.4, 35.6, 32.6, 33.2, 34.3, 32.8, 33.1, 54.7, 55.4, 54.6, 55.1],
   [34.2, 36.1, 33.5, 32.4, 32.1, 33.5, 34.5, 35. , 53.8, 56.9, 54.5, 54.7],
   [33.4, 33.8, 36.2, 33. , 35. , 34.2, 33.8, 33.8, 55.7, 55.2, 56. , 54.5],
   [34.3, 35.9, 34.4, 34.2, 53.5, 54.2, 55.7, 54. , 56.3, 54.4, 55.5, 53.8],
   [34.7, 35.4, 34.7, 33.1, 53.6, 54.5, 54.4, 55.5, 54.7, 55.4, 55.1, 55.6],
   [33.3, 34.3, 33.6, 33.1, 55.4, 55.7, 55.4, 55.4, 55.8, 55. , 55.3, 54.1],
   [33.7, 33.5, 37. , 34.9, 57.6, 54.2, 54.9, 54.6, 56. , 55.7, 55.1, 55.9],
   [34. , 35.1, 33.6, 34.5, 56.2, 55.3, 55.2, 54. , 54.1, 54.5, 54.4, 56. ]])


    
cell_shape = (5,4)

I want to find the average for the average the section for example the first section:

[33.5, 35.3, 33.6, 33.6]
[33.1, 34.2, 34.1, 34.3]
[35.3, 35.4, 35.6, 32.6]
[34.2, 36.1, 33.5, 32.4]
[33.4, 33.8, 36.2, 33. ]

Second section:

[33.5, 33.9, 32.3, 33.2]
[34.7, 31.3, 32.3, 33.4]
[33.2, 34.3, 32.8, 33.1]
[32.1, 33.5, 34.5, 35. ]
[35. , 34.2, 33.8, 33.8] 

and etc.

CodePudding user response:

The current answers works fine, but they may be slow if you want to do this often on large arrays. The operation you want to do is called "strided convolutions using a mean/uniform kernel". There exists many libraries to do said operation (e.g. PyTorch, scikit-image, or a more advanced numpy way using stride tricks) a lot faster than using for-loops in Python.

Here is an example using skimage which avoids for-loops in Python:

import numpy as np
from skimage.util.shape import view_as_windows

temp_array = np.array(
  [[33.5, 35.3, 33.6, 33.6, 33.5, 33.9, 32.3, 33.2, 53.8, 54.6, 53.4, 54.2],
   [33.1, 34.2, 34.1, 34.3, 34.7, 31.3, 32.3, 33.4, 57.5, 55. , 53.5, 56.1],
   [35.3, 35.4, 35.6, 32.6, 33.2, 34.3, 32.8, 33.1, 54.7, 55.4, 54.6, 55.1],
   [34.2, 36.1, 33.5, 32.4, 32.1, 33.5, 34.5, 35. , 53.8, 56.9, 54.5, 54.7],
   [33.4, 33.8, 36.2, 33. , 35. , 34.2, 33.8, 33.8, 55.7, 55.2, 56. , 54.5],
   [34.3, 35.9, 34.4, 34.2, 53.5, 54.2, 55.7, 54. , 56.3, 54.4, 55.5, 53.8],
   [34.7, 35.4, 34.7, 33.1, 53.6, 54.5, 54.4, 55.5, 54.7, 55.4, 55.1, 55.6],
   [33.3, 34.3, 33.6, 33.1, 55.4, 55.7, 55.4, 55.4, 55.8, 55. , 55.3, 54.1],
   [33.7, 33.5, 37. , 34.9, 57.6, 54.2, 54.9, 54.6, 56. , 55.7, 55.1, 55.9],
   [34. , 35.1, 33.6, 34.5, 56.2, 55.3, 55.2, 54. , 54.1, 54.5, 54.4, 56. ]])

cell_shape = (5,4)
sections: np.ndarray = view_as_windows(temp_array, cell_shape, cell_shape)
print(sections.mean((-2,-1)))

result:

[[34.16  33.495 54.96 ]
 [34.365 54.965 55.135]]

CodePudding user response:

sh = temp_array.shape
for y in range(0, sh[0], cell_shape[0]):
    for x in range(0, sh[1], cell_shape[1]):
        print(np.average(temp_array[y:y   cell_shape[0], x:x   cell_shape[1]]))

Prints:

34.16
33.49499999999999
54.96
34.365
54.964999999999996
55.135000000000005

CodePudding user response:

for startx, endx in [ ( n * cell_shape[0], (n 1) * cell_shape[0] ) for n in range( temp_array.shape[0] // cell_shape[0] ) ]:
        for starty, endy in [ ( n * cell_shape[1], (n 1) * cell_shape[1] ) for n in range( temp_array.shape[1] // cell_shape[1] ) ]:
                np.average(temp_array[startx:endx, starty:endy])

Uses np slicing which is in the format, [startx:endx, starty:endy]

This only prints the arrays but making it an average is just a matter of changing it to np.mean

  • Related