Grouping sorted coordinates based on proximity to each other I created an algotrithm that groups a sorted list of coordinates into buckets based on their proximity (30) to one another. 

Steps:


Create a new key with a list value and pop the first point in the list into it
Scan the list of points for points that are close to it. Push matches to the new list and replace values with None
After scan, filter the list, removing None values
Back to one, until points is empty.


I can't modify the list by deleting elements because I use indexes.

After I'm done grouping, I take the average of each group of points. 

def group_points(points):
    groups = {}
    groupnum = 0
    while len(points) &gt; 1:
        groupnum += 1
        key = str(groupnum)
        groups[key] = []
        ref = points.pop(0)
        for i, point in enumerate(points):
            d = get_distance(ref, point)
            if d &lt; 30:
                groups[key].append(points[i])
                points[i] = None
        points = list(filter(lambda x: x is not None, points))
    # perform average operation on each group
    return list([[int(np.mean(list([x[0] for x in groups[arr]]))), int(np.mean(list([x[1] for x in groups[arr]])))] for arr in groups])


def get_distance(ref, point):
    # print('ref: {} , point: {}'.format(ref, point))
    x1, y1 = ref[0], ref[1]
    x2, y2 = point[0], point[1]
    return math.hypot(x2 - x1, y2 - y1)


If possible, I would like to reduce the amount of variables and total loops over the points array. Do I need to use indexes? Is it possible to achieve this in one pass over points?
General comments:

You are basically using the groups dict like a list.  Might as well just use a list.

An empty data structure (list, dict, set, tuple) is False in a boolean context, so while len(points) &gt; 1: can be simplified to while points:

It is generally slower to pop from the front of a list than the back of a list, because after removing the first item all the rest of the items get moved up one spot.

points.pop() actually changes the list passed in.  Make sure that's what you want.

filter(None, points) filters out all "False" items.

[ ... ] creates a list.  So, list( [ ... ] ) is redundant.

You can just use x1, y1 = ref.

Put that all together and you get something like:

def group_points(points):
    groups = []
    while points:
        far_points = []
        ref = points.pop()
        groups.append([ref])
        for point in points:
            d = get_distance(ref, point)
            if d &lt; 30:
                groups[-1].append(point)
            else:
                far_points.append(point)

        points = far_points

    # perform average operation on each group
    return [list(np.mean(x, axis=1).astype(int)) for x in groups]

def get_distance(ref, point):
    # print('ref: {} , point: {}'.format(ref, point))
    x1, y1 = ref
    x2, y2 = point
    return math.hypot(x2 - x1, y2 - y1)


You also might want to look at functions in scipy.cluster.