Remove outliers from N dimensional data I have created a function that will remove outliers from a series of data. Generally the data n dimensional. Loosely, an outlier is considered an outlier if it +/- deviates by 1.5 standard_deviation's from the mean (see code for more detailed explanation of what constitutes an outlier). 

The function can handle N dimensional arrays. It uses numpy and my code admittedly does not utilise numpy's iteration techniques. So I would appreciate how to improve this code and utilise numpy more.

import cv2
import numpy as np 

def remove_outliers(data, thresh=1.5, axis=(0,1), use_median=False):
    # Post: Remove outlier values from data. A value in data is considered an outlier if it is NOT mean-std_deviation*thresh &lt; value &lt; mean+std_deviation*thresh

    res                 = []
    median              = np.median(data, axis) 
    mean, std_dev       = cv2.meanStdDev(data)
    measure             = median if use_median else mean
    lower_thresh        = np.subtract(measure, np.multiply(std_dev, thresh))
    upper_thresh        = np.add(measure, np.multiply(std_dev, thresh))

    # Handle arrays that are n dimensional
    if len(data.shape) == 3:
        data = data.reshape((int(data.size/3), 3))

    for v in data:
        if np.all(v &gt; lower_thresh) and np.all(v &lt; upper_thresh):
            res.append(v)

    return res

if __name__ == "__main__":
    arr = np.array([10,99,12,15,9,2,17,15])
    print(arr)
    print(remove_outliers(arr, axis=0, thresh=1.5))

    arr = np.array([[(0,10,3),(99,255,255),(100,10,9),(45,34,9)]], dtype='uint8')
    print(arr)
    print(remove_outliers(arr, thresh=1.5))
Try to make the input and output types the same

In your example, remove_outliers() takes a NumPy array as input, but returns a regular Python list. It would be nicer to have the function return a NumPy array in this case.

The axis parameter only works when using the median

Make sure that when you specify axes, that the resulting behaviour of the function is what you would expect. If, for some reason, the axis parameter could not work with means, then you should throw an error if the caller explicitly specified which axes to work on.

Don't calculate values you are not going to use

You calculate both the median and the mean, but only use one of them. This is inefficient, just write the code as:

if use_median:
    measure = np.median(data, axis)
else:
    mean, std_dev = cv2.meanStdDev(data)
    measure = mean


I know you always need the standard deviation, but see the next comment.

Avoid using CV2 for something as simple as calculating mean and standard deviation

NumPy has functions for calculating those things as well. By avoiding importing cv2, you reduce the amount of dependencies users would have to install. As a bonus, the NumPy functions for mean and standard deviation also take an axis parameter. So consider writing:

std_dev = np.std(data, axis)

if use_median:
    measure = np.median(data, axis)
else:
    measure = np.mean(data, axis)


Don't special-case 3-dimensional data

Why are you reshaping the input array only if len(data.shape) == 3? Your should aim to make your code work generically with arrays of any number of dimensions.