我有一个列表,其中包含元组对的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 / cluster。类似的东西(或者有元组而不是列表):
[[(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)])]
但当然它并没有产生我想要的结果。 有没有办法以更加pythonic的方式(比下面)完成这个?
我知道可以通过另一次迭代完成:
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)
答案 0 :(得分:1)
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)]