按值对列表进行分组,并保留两者

2024-04-25 12:01:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个包含xy点的元组对的列表(作为元组)。第一个代表一个任意点,第二个代表离该点最近的簇的质心。你知道吗

all_neighbours = 
[((28, 145), (25, 125)), ((65, 140), (44, 105)), ((50, 130), (25, 125)), 
 ((38, 115), (44, 105)), ((55, 118), (44, 105)), ((50, 90),  (44, 105)), 
 ((63, 88 ), (44, 105)), ((43, 83 ), (29, 97 )), ((50, 60),  (55, 63 )),
 ((50, 30 ), (55, 20 ))]

我想创建一个新列表,其中包含由这些点近邻元组创建的新neigbourhoud/集群。类似的事情(或者用元组来分组点而不是列表):

[[(55, 20), (50, 30)], [(25, 125), (28, 145), (50, 130)], 
 [(44, 105), (65, 140), (38, 115), (55, 118), (50, 90), (63, 88)],
 [(55, 63), (50, 60)], [(29, 97),  (43, 83)]]

我试过这样做:

centroids = set(map(lambda x: x[1], all_neighbours))
neighbourhood = [(x, [y[0] for y in all_neighbours if y[1] == x]) for x in centroids]
>>
[((55, 20), [(50, 30)]), ((25, 125), [(28, 145), (50, 130)]),
 ((44, 105), [(65, 140), (38, 115), (55, 118), (50, 90), (63, 88)]),
 ((55, 63), [(50, 60)]), ((29, 97), [(43, 83)])]

但它当然没有产生我想要的结果。 有没有一种方法可以让这件事以一种更像Python的方式(比吼叫)来完成?你知道吗


我知道这可以通过另一个迭代来完成:

neighbourhood = [[y[0] for y in all_neighbours if y[1] == x] for x in centroids]

for neigh,cent in zip(neighbourhood, centroids):
    neigh.append(cent)

Tags: in列表forif代表allcent元组
1条回答
网友
1楼 · 发布于 2024-04-25 12:01:23
import operator, itertools
all_neighbours = [((28, 145), (25, 125)), ((65, 140), (44, 105)),
                  ((50, 130), (25, 125)), ((38, 115), (44, 105)),
                  ((55, 118), (44, 105)), ((50, 90),  (44, 105)),
                  ((63, 88 ), (44, 105)), ((43, 83 ), (29, 97 )),
                  ((50, 60),  (55, 63 )), ((50, 30 ), (55, 20 ))]

按质心对列表排序-

centroid = operator.itemgetter(1)
point = operator.itemgetter(0)

all_neighbours.sort(key = centroid)

使用itertools.groupby生成组

for centre, points in itertools.groupby(all_neighbours, centroid):
    print tuple([centre] + map(point, points))

neighbourhoods = [tuple([centre] + map(point, points)) for centre, points
                  in itertools.groupby(all_neighbours, centroid)]

相关问题 更多 >