2017-03-08 3 views
2

Le code trouve le plus petit élément dans chaque liste, je veux ajouter ce point de données à une liste basée sur la liste d'où il provient. Je veux aussi pouvoir trouver la moyenne de chaque groupe.Comment ajouter des éléments à une liste à partir d'une autre liste?

import numpy as np 

centroids = np.array([[3,44],[5,15],[99,12]]) 
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): 
    lists = [[distance(vector1, vector2) for vector2 in array2] for vector1 in array1] 
    x = 1 
    for i in lists: 
     print ('Distance from Centroid {}:{}\n'.format(x,i)) 
     x=x+1 

    print map(min, zip(*lists)) 

distances(centroids,dataPoints) 

Ma sortie:

Distance from Centroid 1:[40.01249804748511, 42.379240200834182, 59.396969619669989, 55.97320787662612, 17.691806012954132, 41.725292090050132, 20.808652046684813, 65.924198895398035] 

Distance from Centroid 2:[11.401754250991379, 16.278820596099706, 42.059481689626182, 40.792156108742276, 20.248456731316587, 27.018512172212592, 43.657759905886145, 65.520989003524662] 

Distance from Centroid 3:[97.329337817535773, 82.389319696183918, 54.918120870983927, 54.230987451824994, 85.37564055396598, 67.029844099475568, 90.426765949026404, 37.443290453698111] 

[11.401754250991379, 16.278820596099706, 42.059481689626182, 40.792156108742276, 17.691806012954132, 27.018512172212592, 20.808652046684813, 37.443290453698111] 

sortie supplémentaire souhaité:

Cluster 1: [[16,32],[20,56]] 
Cluster 2: [[2,4],[17,4],[45,2],[45,7],[32,14]] 
Cluster 3: [[68,33]] 

List of means :[[18,44],[28.2,6.2],[68,33]] 

Pour cet exemple, la quantité de centroïdes/clusters sont définis. Et si elles sont dynamiques et si les listes de grappes doivent être créées à la volée?

+1

Ce sont des * tableaux *. Non * listes *. Ou au moins, vous semblez mélanger les deux. Pourquoi ne pas s'en tenir aux listes? –

+0

@ juanpa.arrivillaga Si je vérifie le type (listes), il renvoie la valeur 'liste'. Je suis conscient que je commence avec des tableaux numériques. Dans votre concept à la solution du problème, l'utilisation de l'un ou l'autre a-t-elle un avantage sur l'autre? – cparks10

+0

@Oui, 'lists' sera une liste car il s'agit du résultat d'une * compréhension-liste *. Cependant, je ne suis pas sûr de ce que vous essayez de faire. –

Répondre

1

On suppose que, vous êtes dans la situation générale où vous voulez dire « à partir de laquelle la liste qui est compressé a fait l'élément venu de », eh bien, vous devez garder une trace de ce qui suit:

>>> import random 
>>> from pprint import pprint 
>>> ls = [[random.randint(80,200) for _ in range(8)] for _ in range(3)] 
>>> pprint(ls) 
[[114, 196, 185, 192, 129, 183, 150, 189], 
[173, 173, 116, 135, 109, 87, 80, 88], 
[159, 173, 139, 189, 100, 107, 102, 188]] 
>>> [min(zip(l,range(len(l)))) for l in zip(*ls)] 
[(114, 0), (173, 1), (116, 1), (135, 1), (100, 2), (87, 1), (80, 1), (88, 1)] 

appliquée à votre situation:

>>> import numpy as np 
>>> 
>>> centroids = np.array([[3,44],[5,15],[99,12]]) 
>>> 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) 
... 
>>> lists = [[distance(vector1, vector2) for vector2 in dataPoints] for vector1 in centroids] 
>>> pprint(lists) 
[[40.01249804748511, 
    42.379240200834182, 
    59.396969619669989, 
    55.97320787662612, 
    17.691806012954132, 
    41.725292090050132, 
    20.808652046684813, 
    65.924198895398035], 
[11.401754250991379, 
    16.278820596099706, 
    42.059481689626182, 
    40.792156108742276, 
    20.248456731316587, 
    27.018512172212592, 
    43.657759905886145, 
    65.520989003524662], 
[97.329337817535773, 
    82.389319696183918, 
    54.918120870983927, 
    54.230987451824994, 
    85.37564055396598, 
    67.029844099475568, 
    90.426765949026404, 
    37.443290453698111]] 
>>> smallest = [min(zip(l,range(len(l)))) for l in zip(*lists)] 
>>> smallest 
[(11.401754250991379, 1), (16.278820596099706, 1), (42.059481689626182, 1), (40.792156108742276, 1), (17.691806012954132, 0), (27.018512172212592, 1), (20.808652046684813, 0), (37.443290453698111, 2)] 

Nous aurions pu être intelligent et ne pas apporté la valeur minimale, mais il n'a pas vraiment d'importance.

Comme vous pouvez avoir autant de centriods, pour le rendre dynamique, ne pas utiliser les variables , utilisez un récipient . Une liste ferait, mais dict s sont faciles:

>>> clusters = {} 
>>> for j, (_, i) in enumerate(smallest): 
...  clusters.setdefault(i,[]).append(dataPoints[j]) 
... 

Enfin,

>>> pprint(clusters) 
{0: [array([16, 32]), array([20, 56])], 
1: [array([2, 4]), 
    array([17, 4]), 
    array([45, 2]), 
    array([45, 7]), 
    array([32, 14])], 
2: [array([68, 33])]} 

Enfin, je tiendrais avec soit des listes ou np.arrays. Rarement sont tous les deux appropriés. Et vous devriez comprendre les avantages et les inconvénients de chacun, afin de savoir quelle est la structure de données appropriée pour votre problème. C'est un aspect très important de l'écriture de code.

+0

Fonctionne comme un charme! J'ai joué avec la recherche de la valeur moyenne de chaque 'cluster', y a-t-il une fonction intégrée qui pourrait m'aider avec ça? Je vais certainement accorder plus d'attention au type de données que j'utilise la prochaine fois. – cparks10

+0

@ cparks10 Si vous avez une liste de tableaux, c'est en fait assez simple: 'means = {k: sum (v)/len (v) pour k, v dans clusters.items()}'. –

+0

@ juanpa.arrivillaga Et si je voulais simplement que les valeurs reviennent et non les clés? Donc, au lieu de {0: array ([18, 44]), 1: array ([2, 4]), 2: array ([41, 12])} je voudrais juste obtenir [[18,44], [ 2,4], [41,12]] ou quel que soit le meilleur format à utiliser pour comparer les moyennes à des tableaux/listes de centroïdes originaux? – cparks10