Min and max are quite easy. Iterate through the items setting the min and max to the new value if required. For the median sort the columns (at least to just over half way) and return the middle item ( length is odd, or the average of the two items closest to the middle ( length is even ).
import numpy as np
arr = np.array([[ 5., 162., 60.], [ 2., 110., 60.], [ 12., 101., 101.],
[ 12., 105., 37.], [ 13., 155., 58.], [ 4., 101., 42.],
[ 8., 101., 38.], [ 6., 125., 40.], [ 15., 200., 40.],
[ 17., 251., 250.], [ 17., 120., 38.], [ 13., 210., 115.],
[ 14., 215., 105.], [ 1., 50., 50.], [ 6., 70., 31.],
[ 12., 210., 120.], [ 4., 60., 25.], [ 11., 230., 80.],
[ 15., 225., 73.], [ 2., 110., 43.]] )
def minmax( arr ):
""" Return min & max arrays of a 2d array. """
mn = arr[0].copy()
mx = arr[0].copy()
for row in arr[1:]:
mn = np.minimum(mn, row) # Item by item minimum
mx = np.maximum(mx, row) # item by item maximum
return mn, mx
def median( arr ):
data = arr.copy() # data will be modified.
# Sort lowest 'half'+1 of data. Once the middle two items are known
# the median can be calculated so no need top sort all.
size = len(data)
for ix, d in enumerate( data[:size // 2 + 1 ] ):
mn = d # Set mn to the next item in the array
mnix = ix # Set mnix to the next index
# Find min in the rest of the array
for jx, s in enumerate( data[ ix+1: ] ):
if s < mn: # If a new mn
mn = s # Set mn to s
mnix = jx + ix+1 # Set mnix to the index
# Swap contents of data[ix] and data[mnix], the minimum found.
# If mnix == ix it still works.
data[ix], data[mnix] = mn, data[ix]
key0 = (size - 1) // 2
key1 = size - 1 - key0
return 0.5 * ( data[key0] + data[key1] )
# Return average of the two middle keys
# ( the keys are the same if a odd number of items in arr)
def medians( arr ):
res = np.zeros_like( arr[0] )
# Iterate through arr transposed. i.e. column by column
for ix, col in enumerate( arr.T ):
res[ix] = median( col )
return res
print( minmax( arr ), medians( arr ) )
# (array([ 1., 50., 25.]), array([ 17., 251., 250.])) [ 11.5 122.5 54. ]
# Numpy versions
print( arr.min( axis = 0 ), arr.max( axis = 0 ), np.median( arr, axis = 0 ))
# [ 1. 50. 25.] [ 17. 251. 250.] [ 11.5 122.5 54. ]
It shows how much effort numpy saves you and it runs faster too.