2015-03-03 2 views
1

У меня есть список, который содержит пары кортежей xy-points (в виде кортежей). Первая представляет собой произвольную точку, а вторая - центроид кластера, который является ближайшим соседом к этой точке.Список групп по значениям и сохранить как

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)])] 

Но, конечно, это не дало результата я хотел. Есть ли способ сделать это более путинским способом (чем ниже)?


Я знаю, что это можно сделать с помощью следующей итерации:

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

Вы хотите сгруппировать точки своими центроидами, где центроид - это один из каждого кортежа? – wwii

+0

центроид - это элемент два каждого кортежа (многие точки могут быть назначены одному и тому же центру). Я уже могу их сгруппировать, но не могу получить форму, в которой я нуждаюсь (в основном, выражать соседства, а не отношения). Разве это не ясно в вопросе? – igavriil

+0

Отправьте ожидаемый результат для ваших данных примера. – wwii

ответ

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))] 

Сортировать список по centroids-

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)] 
+0

Мне уже удалось произвести этот результат, как вы можете видеть по моему вопросу. Я хочу, например, '((25, 125), [(28, 145), (50, 130)])' быть '((25, 125), (28, 145), (50, 130))' , Хотя это хороший подход – igavriil

+0

См. Edit ... Это то, что вы хотите? – wwii

Смежные вопросы