Q:

More efficient way to get nearest center

My data object is an instance of:
class data_instance:
    def __init__(self, data, tlabel):
        self.data = data # 1xd numpy array
        self.true_label = tlabel # integer {1,-1}

So far in code, I have a list called data_history full with data_istance and a set of centers (numpy array with shape (k,d)).
For a given data_instance new_data, I want:

1/ Get the nearest center to new_data from centers (by euclidean distance) let it be called Nearest_center.
2/ Iterate trough data_history and:

2.1/ select elements where the nearest center is Nearest_center (result of 1/) into list called neighbors.
2.2/ Get labels of object in neighbors.

Bellow is my code which work but it steel slow and I am looking for something more efficient.
My Code
For 1/
def getNearestCenter(data,centers):

    if centers.shape != (1,2):
        dist_ = np.sqrt(np.sum(np.power(data-centers,2),axis=1)) # This compute distance between data and all centers

        center = centers[np.argmin(dist_)] # this return center which have the minimum distance from data

    else:
        center=centers[0]
    return center

For 2/ (To optimize)
def getLabel(dataPoint, C, history):

    labels = []
    cluster = getNearestCenter(dataPoint.data,C)
    for x in history:
        if  np.all(getNearestCenter(x.data,C) == cluster):
            labels.append(x.true_label)
    return labels

A:

You should rather use the optimized cdist from scipy.spatial which is more efficient than calculating it with numpy,
from scipy.spatial.distance import cdist

dist = cdist(data, C, metric='euclidean')
dist_idx = np.argmin(dist, axis=1)

An even more elegant solution is to use scipy.spatial.cKDTree (as pointed out by @Saullo Castro in comments), which could be faster for a large dataset,
from scipy.spatial import cKDTree

tr = cKDTree(C)
dist, dist_idx = tr.query(data, k=1) 

