2017-03-07 82 views
0

這是一個K均值算法。這是作業,所以我不想使用內置Kmeans功能的 。 我有2個numpy數組。一個是質心。另一個是數據點。 我正試圖找出每個質心到每個數據點的距離。 我不知道如何將數組傳遞給我的函數以便打印。我想最終與 一樣多的距離陣列的質心。然後我可以比較陣列中的每個距離,選擇最小的距離並將該點分配給其中一個羣集。然後找到每個簇的平均值,這些數字就成爲我的新質心。如何找到不同numpy陣列中兩點之間的距離?

import numpy as np 

centroids = np.array([[3,44],[5,15]]) 
dataPoints = np.array([[2,4],[17,4],[45,2],[45,7],[16,32],[32,14],[20,56],[68,33]]) 
def distance(a,b): 
    for x in a: #for each point in centroids array 
     for y in b:#for each point in the dataPoints array 
      print np.sqrt((a[0] - b[0])**2 + (a[1] - b[1])**2)#print the distance 

distance (randPoints, dataPoints)#call the function with the data 

輸出我得到:

[ 12.04159458 41.48493703] 
[ 12.04159458 41.48493703] 
[ 12.04159458 41.48493703] 
[ 12.04159458 41.48493703] 
[ 12.04159458 41.48493703] 
[ 12.04159458 41.48493703] 
[ 12.04159458 41.48493703] 
[ 12.04159458 41.48493703] 
[ 12.04159458 41.48493703] 
[ 12.04159458 41.48493703] 
[ 12.04159458 41.48493703] 
[ 12.04159458 41.48493703] 
[ 12.04159458 41.48493703] 
[ 12.04159458 41.48493703] 
[ 12.04159458 41.48493703] 
[ 12.04159458 41.48493703] 

我在做什麼這顯然是錯誤的嗎?我應該最終得到2個不同的陣列,每個陣列有8個距離。

+1

你一直提到了'和'B'的'同第一要素。使用'x [i]'和'y [i]'代替'a [i]'和'b [i]'。 – DyZ

+1

我不知道爲什麼你期望2個8容器的容器。看看你的循環。您正在遍歷質心中2個元素中的每個元素,並且在這裏循環遍歷8個dataPoints元素中的每個元素。每次打印。所以你要打印16件東西。 – Denziloe

+0

順便說一句,你的內循環可以用'print(np.sqrt(((dataPoints-x)** 2).sum(axis = 1)))'代替。 – DyZ

回答

1
import numpy as np 

centroids = np.array([[3,44],[5,15]]) 
dataPoints = np.array([[2,4],[17,4],[45,2],[45,7],[16,32],[32,14],[20,56],[68,33]]) 

def size(vector): 
    return np.sqrt(sum(x**2 for x in vector)) 

def distance(vector1, vector2): 
    return size(vector1 - vector2) 

def distances(array1, array2): 
    return [[distance(vector1, vector2) for vector2 in array2] for vector1 in array1] 

print(distances(centroids, dataPoints)) 
2

我生病想出變身爲距離計算1,第2和3D陣列,所以我拼湊模仿從SciPy的pdist和cdist功能,但使用einsum,很多人在使用這個網站。至少在我的腦海中很容易遵循,而愛因斯坦也可以用於其他目的。所以考慮以下幾點。您可以使用,然後使用排序(排序,argsort等),如果你需要提取最接近-x值等。希望你覺得它有用

a = np.array([[1, 2], [3, 4], [5, 6]]) 
b = np.array([[6, 5], [4, 3], [2, 1]]) 

def e_dist(a, b, metric='euclidean'): 
    """Distance calculation for 1D, 2D and 3D points using einsum 
    : a, b - list, tuple, array in 1,2 or 3D form 
    : metric - euclidean ('e','eu'...), sqeuclidean ('s','sq'...), 
    :----------------------------------------------------------------------- 
    """ 
    a = np.asarray(a) 
    b = np.atleast_2d(b) 
    a_dim = a.ndim 
    b_dim = b.ndim 
    if a_dim == 1: 
     a = a.reshape(1, 1, a.shape[0]) 
    if a_dim >= 2: 
     a = a.reshape(np.prod(a.shape[:-1]), 1, a.shape[-1]) 
    if b_dim > 2: 
     b = b.reshape(np.prod(b.shape[:-1]), b.shape[-1]) 
    diff = a - b 
    dist_arr = np.einsum('ijk,ijk->ij', diff, diff) 
    if metric[:1] == 'e': 
     dist_arr = np.sqrt(dist_arr) 
    dist_arr = np.squeeze(dist_arr) 
    return dist_arr 

e_dist(a, b) 
array([[ 5.8, 3.2, 1.4], 
     [ 3.2, 1.4, 3.2], 
     [ 1.4, 3.2, 5.8]]) 

e_dist(a[0], b) 
array([ 5.8, 3.2, 1.4]) 

e_dist(a[:2], b) 
array([[ 5.8, 3.2, 1.4], 
     [ 3.2, 1.4, 3.2]])