2017-11-25 610 views
0

我有以下數據:Python:如何在k-means中將特定數據點的初始質心?

import pandas as pd 
import random 
import matplotlib.pyplot as plt 

df = pd.DataFrame() 
df['x'] = [3, 2, 4, 3, 4, 6, 8, 7, 8, 9] 
df['y'] = [3, 2, 3, 4, 5, 6, 5, 4, 4, 3] 
df['val'] = [1, 10, 1, 1, 1, 8, 1, 1, 1, 1] 

k = 2 
centroids = {i + 1: [np.random.randint(0, 10), np.random.randint(0, 10)] for i in range(k)} 

plt.scatter(df['x'], df['y'], color='blue') 
for i in centroids.keys(): 
    plt.scatter(*centroids[i], color='red', marker='^') 
plt.show() 

plot centroid

我希望把數據點的初始質心與最高值。然後,在這種情況下,質心應位於座標爲(2,2)和(6,6)的數據點上。

x y val 
0 3 3 1 
1 2 2 10 
2 4 3 1 
3 3 4 1 
4 4 5 1 
5 6 6 8 
6 8 5 1 
7 7 4 1 
8 8 4 1 
9 9 3 1 
+0

您在使用scikit的KMeans估計器學習?如果是這樣,你可以通過一個數組給予初始中心。請參閱'init'參數[here](http://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html)。或者你是問如何構建這個數組呢? –

+0

@MarkDickinson是的,我問如何編寫Python代碼讓我把質心放在具有最高值的節點上,因爲我沒有在這裏使用scikit學習。我爲kmeans寫了自己的代碼。 – arizamoona

回答

1

您可以通過val列進行排序數據框獲得頂級k值的索引,然後切片用df.iloc數據幀。


以降序排序:通過highest_points_as_centroids.values

array([[2, 2], 
     [6, 6]], dtype=int64) 

k=2 # Number of centroids 
highest_points_as_centroids = df.iloc[0:k,[0,1]] 

print(highest_points_as_centroids) 

    x y 
1 2 2 
5 6 6 

可以得到X,Y的值作爲numpy的數組:

df = df.sort_values('val', ascending=False) 
print(df) 

    x y val 
1 2 2 10 
5 6 6 8 
0 3 3 1 
2 4 3 1 
3 3 4 1 
4 4 5 1 
6 8 5 1 
7 7 4 1 
8 8 4 1 
9 9 3 1 

切片數據幀


EDIT1:

更簡潔(由@sharatpc建議)

df.nlargest(2, 'val')[['x','y']].values 
array([[2, 2], 
    [6, 6]], dtype=int64) 

EDIT2:

由於OP評論說,他們想要的重心是在一本字典:

centroids = highest_points_as_centroids.reset_index(drop=True).T.to_dict('list') 
print(centroids) 
{0: [2L, 2L], 1: [6L, 6L]} 

如果字典鍵嚴格需要從1開始:

highest_points_as_centroids.reset_index(drop=True, inplace=True) 
highest_points_as_centroids.index +=1 
centroids = highest_points_as_centroids.T.to_dict('list') 
print(centroids) 
{1: [2L, 2L], 2: [6L, 6L]} 
+1

您不需要切分數據幀。只需使用nlargest即可獲得前2名:'df.nlargest(2,'val')';或'df.sort_values('val',ascending = False).head(2)' – skrubber

+0

如果你想要輸出x和y,那麼:'df.nlargest(k,'val')[['x',' y']]'或'df.sort_values('val',ascending = False)[['x','y']]。頭(k)' – skrubber

+0

謝謝!不知道「最大」。我補充說,答案。 – akilat90

0

只是回答@ arzamoona的其他問題,在同一個地方:

import pandas as pd 
import random 
import matplotlib.pyplot as plt 

df = pd.DataFrame() 
df['x'] = [3, 2, 4, 3, 4, 6, 8, 7, 8, 9] 
df['y'] = [3, 2, 3, 4, 5, 6, 5, 4, 4, 3] 
df['val'] = [1, 10, 1, 1, 1, 8, 1, 1, 1, 1] 

k = 2 
centroids=df.nlargest(k, 'val')[['x','y']] 

plt.scatter(df['x'], df['y'], color='blue') 
plt.scatter(centroids.x, centroids.y, color='red', marker='^') 
plt.show() 

enter image description here

然後到質心值添加到字典:

{i:v for i,v in enumerate(centroids.values.tolist())} 
{0: [2, 2], 1: [6, 6]} 
+0

您可以使用'to_dict'將質心轉換爲沒有for循環的字典。 – akilat90

+0

但這會產生差異:'{'x':{1:2,5:6},'y':{1:2,5:6}} – skrubber

+0

您必須更改'orient'參數。檢查我的回答 – akilat90