2017-11-25 3 views
0

Ich habe folgende Daten:Python: Wie man Anfangsschwerpunkte auf spezifische Datenpunkte in k-Mitteln setzt?

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

Ich möchte mit dem höchsten Wert der anfänglichen Zentroide auf Datenpunkte setzen. In diesem Fall sollten die Schwerpunkte auf Datenpunkten mit den Koordinaten (2, 2) und (6, 6) liegen.

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

Sie verwenden der 'KMeans' Schätzer von scikit lernen? Wenn dies der Fall ist, können Sie ein Array übergeben, das die Anfangszentren enthält. Siehe den Parameter 'init' [hier] (http://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html). Oder fragen Sie sich, wie dieses Array überhaupt aufgebaut wird? –

+0

@MarkDickinson Ja, ich frage, wie man Python-Code schreibt, damit ich die Zentroide auf den Knoten mit dem höchsten Wert platziere, weil ich hier nicht scikit learn benutzt habe. Ich habe meine eigenen Codes für Kmeans geschrieben. – arizamoona

Antwort

1

Sie können die Datenrahmen von val Spalte sortieren die Indizes von oben k Werte zu erhalten und dann den Datenrahmen schneiden df.iloc verwenden.


in der absteigenden Reihenfolge Reihenfolge:

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 

Schneidens des Datenrahmens:

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 

Sie das X erhalten, y-Werte als numpy Array von highest_points_as_centroids.values

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

EDIT1:

Oder kurz und bündig (wie von @sharatpc vorgeschlagen)

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

EDIT2:

Wie OP bemerkte, dass sie die Schwer wollen in einem Wörterbuch sein:

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

Wenn die Wörterverzeichnisschlüssel unbedingt benötigt werden, um von 1:

zu starten 10
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

müssen Sie den Datenrahmen nicht in Scheiben schneiden. benutze nlargest, um die oberste 2 zu erhalten: 'df.nlargest (2, 'val')'; oder 'df.sort_values ​​('val', aufsteigend = Falsch) .head (2)' – skrubber

+0

Wenn Sie x und y von den Ausgaben wollen, dann: 'df.nlargest (k, 'val') [['x', ' y ']] 'oder' df.sort_values ​​(' val ', aufsteigend = Falsch) [[' x ',' y ']]] head (k) ' – skrubber

+0

Danke! Ich wusste nicht von "größter". Ich fügte das der Antwort hinzu. – akilat90

0

einfach zu beantworten @ arzamoona die weiteren Fragen, an einem Ort:

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

Und dann die Schwerpunktwerte zu einem Wörterbuch hinzuzufügen:

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

Sie können verwenden 'to_dict', um die Zentroide ohne For-Schleife in ein Dictionary zu konvertieren. – akilat90

+0

aber das würde einen Spread geben: '{'x': {1: 2, 5: 6}, 'y': {1: 2, 5: 6}}' – skrubber

+0

Sie müssen das 'orient'-Argument ändern. Überprüfen Sie die Edit2 meiner Antwort – akilat90

Verwandte Themen