[Math] Algorithm to separate an array of numbers into “low”, “medium” and “high” ranges

algorithmsaveragemedian

this is my first post on Math-Exchange. I'm a programmer, and I work with object-oriented algorithms, but when things gets too "algebraic" I get stuck. So I thought I'd ask over here.

I need to create an algorithm that would parse an array of numbers and calculate the 'High', 'Mid' and 'Low' ranges from two constants: $L$ = lowest number in the given array; and $H$ = highest number.


Suppose I have an array of numbers, with 1 being the lowest; and 6 being the highest:

I need to calculate:

  • "High range": 5 to 6

  • "Mid range" : 3 to 4

  • "Low range" : 1 to 2


Basically it's a plain old Arithmetic Median Average, but with 2 medians, instead of one.

So far when I parse through each number to determine its group, I only came up the "Star Rating" formula

assigned_group = ((target_number / max_value) / 3)

but this only works if the lowest number is 1, and I need it to be dynamic.

Thank you in advance.

Best Answer

It's a little bit unclear what you want, so I'm going to present several possible answers that you can choose from.

  • The simplest possibility is that you simply want to divide the range into three equal parts. Assuming that the lowest number is $L$ and the highest is $H$, you can calculate the ranges as:

    1. from $L$ to $L + \frac{H-L}3$,
    2. from $L + \frac{H-L}3$ to $L + 2\frac{H-L}3$ and
    3. from $L + 2\frac{H-L}3$ to $H$.

    In fact, a simple way to assign a number $n$ into one of these ranges is to subtract $L$ from it, multiply the result by $3$, divide it by $H-L$ and truncate it to the next lowest integer:

    group = int( (n - L) * 3 / (H - L) );
    

    This will give you a number from $0$ to $2$, or possibly $3$ if $n = H$. To avoid that last case, you can either replace $H$ in the formula with $H+1$ (if working with integers) or $H + \epsilon$ for some very small number $\epsilon$ (if working with floats), or just check for it afterwards, e.g.:

    if (group > 2) group = 2;
    

    Obviously, you can use the exact same method for more groups than 3 as well.

  • Another possibility is that you want to divide the numbers into three groups of equal size, such that all numbers in group 1 are less than or equal to those in group 2, which are less than or equal to those in group 3. In other words, you want to divide your numbers into three quantiles.

    The simplest way to do this programmatically is just to sort your list of numbers, and then split the sorted list into three parts of (approximately) equal length. In pseudocode, using Python-like array slice notation:

    list.sort();
    n = list.length;
    part1 = list[0 : n/3];
    part2 = list[n/3 : 2*n/3];
    part3 = list[2*n/3 : n];
    
Related Question