【问题标题】:How I select/format only the values from a dictionary into a list or numpy array?如何仅将字典中的值选择/格式化为列表或 numpy 数组?
【发布时间】:2017-07-29 19:47:07
【问题描述】:

如何让它只打印平均值列表? 我只需要它与我的 np 格式完全相同 数组,以便我可以比较它们以查看它们是否相同。

代码:

import numpy as np
from pprint import pprint

centroids = np.array([[3,44],[4,15],[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):
    lists = [[distance(vector1, vector2) for vector2 in array2] for vector1 in array1]
    #print lists.index(min, zip(*lists))
    smallest = [min(zip(l,range(len(l)))) for l in zip(*lists)]
    clusters = {}
    for j, (_, i) in enumerate(smallest):
        clusters.setdefault(i,[]).append(dataPoints[j])
    pprint (clusters)
    print'\nAverage of Each Point'
    avgDict = {}
    for k,v in clusters.iteritems():
        avgDict[k] = sum(v)/ (len(v))
    avgList = np.asarray(avgDict)
    pprint (avgList)

distances(centroids,dataPoints)

电流输出:

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

Average of Each Point
array({0: array([18, 44]), 1: array([2, 4]), 2: array([41, 12])}, dtype=object)

期望的输出:

[[18,44],[2,4],[41,12]]

或者任何比较我的数组/列表的最佳格式。我知道我应该坚持使用一种数据类型。

【问题讨论】:

    标签: python arrays list dictionary


    【解决方案1】:

    您是否尝试通过最近的centroids 的索引对dataPoints 进行聚类,并找出聚类点的平均位置?如果是的话,我建议使用numpy的一些广播规则来获得你需要的输出。

    考虑一下,

        np.linalg.norm(centroids[None, :, :] - dataPoints[:, None, :], axis=-1)
    

    它创建一个矩阵,显示dataPointscentroids 之间的所有距离,

        array([[ 40.01249805,  11.18033989,  11.40175425],
               [ 42.3792402 ,  17.02938637,  16.2788206 ],
               [ 59.39696962,  43.01162634,  42.05948169],
               [ 55.97320788,  41.77319715,  40.79215611],
               [ 17.69180601,  20.80865205,  20.24845673],
               [ 41.72529209,  28.01785145,  27.01851217],
               [ 20.80865205,  44.01136217,  43.65775991],
               [ 65.9241989 ,  66.48308055,  65.520989  ]])
    

    您可以通过这个技巧计算最近质心的索引(为了便于阅读,它们被分成 3 行),

        In: t0 = centroids[None, :, :] - dataPoints[:, None, :]
        In: t1 = np.linalg.norm(t0, axis=-1)
        In: t2 = np.argmin(t1, axis=-1)
    

    现在t2 有了索引,

        array([1, 2, 2, 2, 0, 2, 0, 2])
    

    要查找 #1 集群,请使用布尔掩码 t2 == 0

        In: dataPoints[t2 == 0]
        Out: array([[16, 32],
                    [20, 56]])
    
        In: dataPoints[t2 == 1]
        Out: array([[2, 4]])
    
        In: dataPoints[t2 == 2]
        Out: array([[17,  4],
                    [45,  2],
                    [45,  7],
                    [32, 14],
                    [68, 33]])
    

    或者只是计算你的情况的平均值,

        In: np.mean(dataPoints[t2 == 0], axis=0)
        Out: array([ 18.,  44.])
    
        In: np.mean(dataPoints[t2 == 1], axis=0)
        Out: array([ 2.,  4.])
    
        In: np.mean(dataPoints[t2 == 2], axis=0)
        Out: array([ 41.4,  12. ])
    

    当然,如果您愿意,可以在 for 循环中重写后面的块。

    在我看来,通过 numpy 的约定来制定解决方案可能是一个好习惯。

    【讨论】:

    • 工作就像一个魅力!正是我想要的!
    • 程序运行良好,但我经常收到“空切片平均值”错误。你介意在这方面给我一点帮助吗?另一位用户提出了一个可行的解决方案,但它并没有让我得到所需的集群数量。这是帖子的链接:stackoverflow.com/questions/43100855/…
    猜你喜欢
    • 1970-01-01
    • 2018-04-19
    • 1970-01-01
    • 2016-12-17
    • 2020-08-22
    • 1970-01-01
    • 1970-01-01
    • 2021-12-06
    • 1970-01-01
    相关资源
    最近更新 更多