<jupyter_start><jupyter_text>stime = time.time()for _ in range(1000):    y = np.random.rand(1,2)*500    print(f'y value is: {y}')    distances = spatial.distance_matrix(X,y)    print(f'minimum distance is: {np.amin(distances)}')    print(f'it occurs at: {np.where(distances==np.amin(distances))}')    print(f'that point is: {X[np.where(distances==np.amin(distances))[0]]}')    print('---------------------')etime = time.time()print(f'that took: {etime - stime} seconds') That finds the value for k=1 but I think I can find the higher values of k with a single function. np.argpartition shows potential in my research<jupyter_code>class KNearestNeighbors():
    def __init__(self, neighbors):
        self.neighbors = neighbors

    def fit(self, data):
        self.data = data

    def predict(self, y):
        dist = spatial.distance_matrix(self.data, y)
        kmin_index = np.argsort(dist, axis=0)
        return self.data[kmin_index[:self.neighbors]], dist[kmin_index[:self.neighbors]]
X = np.random.rand(50,2)*100
y = np.random.rand(1,2) *100

neigh = KNearestNeighbors(5)
neigh.fit(X)
neigh.predict(y)
np.__version__
# figuring out how argsort works
dist = spatial.distance_matrix(X, y)
np.argsort(dist, axis=0)
# working out getting average distance
distances = []
for x in X:
    y = spatial.distance_matrix(X, x.reshape(1,2))
    distances.append(np.squeeze(y))
np.array(distances).mean(0)
# figuring out how distance matrix works
y = X[0].reshape(1,2)
spatial.distance_matrix(X, y)
from k_means_clustering import KMeansClustering
def get_distances(X):
        '''this little helper function builds out the 
        distances matrix'''
        distances = []
        for x in X:
            y = spatial.distance_matrix(X, x.reshape(1,2))
            distances.append(np.squeeze(y))
        distances = np.array(distances)
        return distances, distances.mean(0)
k = 3
cluster = KMeansClustering(k)
# cluster.fit(X)
X = np.random.rand(500,2)*100
x, y = X.T
# Select K random points from x 
# to grab a random row from numpy one has to generate a number then grab that row
c_ids = np.random.randint(X.shape[0], size=k)
centers = X[c_ids]
previous = np.random.rand(k, 2).squeeze()

while np.all(previous != centers):
    print('in loop')
    previous = centers.copy()
    # this part needs to loop
    # get the distance from each point to the center
    distances = spatial.distance_matrix(X, centers)
    # Assign to centers
    assignments = np.argmin(distances, axis=1)

    #display the data
    plt.scatter(x, y, c=assignments)
    cx, cy = centers.T
    plt.scatter(cx, cy, c='b')
    # Calculate new means #this is the part that needs fixing
    for i in range(k):
        distances, means = get_distances(X[assignments == i])
        centers[i] = X[assignments == i][np.argmin(means)]
        
    cx, cy = centers.T
    plt.scatter(cx, cy, c='r')
    plt.show()


plt.scatter(x, y, c=assignments)
plt.scatter(cx, cy, c='r')
print(centers)
# and working on predict
y = np.random.rand(1,2) *100
# get the distances
dists = spatial.distance_matrix(centers, y)
# get which center is closest
cent = np.argmin(dists)

X[assignments == 2]
centers[2]<jupyter_output><empty_output>