Есть ли способ разбить список координат на отдельные части, основываясь на повторяющихся значениях? - PullRequest
0 голосов
/ 11 апреля 2019

Я пытаюсь нарисовать несколько отдельных геометрий, используя matplotlib.pyplot, основываясь на серии координат. Мой текущий список координат, содержащий две геометрии, выглядит так:

coords = [(0.0, -0.31), (2.73, -0.31), (2.73, 0.33), (2.02, 0.95), (1.77, 2.44), (1.39, 4.76), (0.64, 4.76), (0.0, 3.46), (0.0, 0.33), (0.0, -0.31), (2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]    

Я хотел бы разделить этот список на отдельные списки, основанные на повторяющихся значениях, для создания и построения замкнутых геометрий. В настоящее время этот набор координат правильно отображает две фигуры, но они связаны линией. Я хотел бы, чтобы они были отдельными, поэтому линия, связывающая их, не отображается.

Можно ли разделить этот список таким образом, чтобы при повторном достижении первого значения (0, -0,31) (т. Е. При закрытии геометрии) создавался новый список с координатами вплоть до этой точки и включительно? Это выделит все координаты, связанные с замкнутой формой, что позволит мне построить ее.

Исходный список координат может содержать n числовых геометрий внутри него, поэтому в идеале решение должно разбить их все на отдельные списки пар координат, где первая и последняя пары координат совпадают.

Ответы [ 2 ]

0 голосов
/ 11 апреля 2019

Я бы использовал собственный генератор:

from itertools import takewhile

coords = [(0.0, -0.31), (2.73, -0.31), (2.73, 0.33), (2.02, 0.95), (1.77, 2.44), (1.39, 4.76), (0.64, 4.76), (0.0, 3.46), (0.0, 0.33), (0.0, -0.31), (2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]

def coord_list(coords):
    coord_iter = iter(coords)
    while True:
        start = next(coord_iter)
        yield [start, *takewhile(lambda x: x != start, coord_iter), start]

list(coord_list(coords))

Выход:

[[(0.0, -0.31),
  (2.73, -0.31),
  (2.73, 0.33),
  (2.02, 0.95),
  (1.77, 2.44),
  (1.39, 4.76),
  (0.64, 4.76),
  (0.0, 3.46),
  (0.0, 0.33),
  (0.0, -0.31)],
 [(2.73, -0.43),
  (2.73, -3.5),
  (6.73, -3.5),
  (6.73, -3.0),
  (6.73, -2.0),
  (6.73, -0.43),
  (2.73, -0.43)]]
0 голосов
/ 11 апреля 2019

Вы можете использовать itertools.groupby:

import itertools
coords = [(0.0, -0.31), (2.73, -0.31), (2.73, 0.33), (2.02, 0.95), (1.77, 2.44), (1.39, 4.76), (0.64, 4.76), (0.0, 3.46), (0.0, 0.33), (0.0, -0.31), (2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)] 
c = [[a, list(b)] for a, b in itertools.groupby(coords, key=lambda x:x == coords[0])]
new_result = [c[i][-1]+c[i+1][-1] for i in range(0, len(c), 2)]

Выход:

[[(0.0, -0.31), (2.73, -0.31), (2.73, 0.33), (2.02, 0.95), (1.77, 2.44), (1.39, 4.76), (0.64, 4.76), (0.0, 3.46), (0.0, 0.33)], [(0.0, -0.31), (2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]]

Редактировать: чтобы найти все группы, вы можете использовать генератор:

def groups(data):
  for i, a in enumerate(data):
     c = [[a, list(b)] for a, b in itertools.groupby(data[i:], key=lambda x:x == a)]
     yield [c[i][-1]+c[i+1][-1] for i in range(0, len(c)-1, 2)]

print(list(groups(coords)))

Вывод:

[[[(0.0, -0.31), (2.73, -0.31), (2.73, 0.33), (2.02, 0.95), (1.77, 2.44), (1.39, 4.76), (0.64, 4.76), (0.0, 3.46), (0.0, 0.33)], [(0.0, -0.31), (2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]], [[(2.73, -0.31), (2.73, 0.33), (2.02, 0.95), (1.77, 2.44), (1.39, 4.76), (0.64, 4.76), (0.0, 3.46), (0.0, 0.33), (0.0, -0.31), (2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]], [[(2.73, 0.33), (2.02, 0.95), (1.77, 2.44), (1.39, 4.76), (0.64, 4.76), (0.0, 3.46), (0.0, 0.33), (0.0, -0.31), (2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]], [[(2.02, 0.95), (1.77, 2.44), (1.39, 4.76), (0.64, 4.76), (0.0, 3.46), (0.0, 0.33), (0.0, -0.31), (2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]], [[(1.77, 2.44), (1.39, 4.76), (0.64, 4.76), (0.0, 3.46), (0.0, 0.33), (0.0, -0.31), (2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]], [[(1.39, 4.76), (0.64, 4.76), (0.0, 3.46), (0.0, 0.33), (0.0, -0.31), (2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]], [[(0.64, 4.76), (0.0, 3.46), (0.0, 0.33), (0.0, -0.31), (2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]], [[(0.0, 3.46), (0.0, 0.33), (0.0, -0.31), (2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]], [[(0.0, 0.33), (0.0, -0.31), (2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]], [[(0.0, -0.31), (2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]], [[(2.73, -0.43), (2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43)]], [[(2.73, -3.5), (6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]], [[(6.73, -3.5), (6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]], [[(6.73, -3.0), (6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]], [[(6.73, -2.0), (6.73, -0.43), (2.73, -0.43)]], [[(6.73, -0.43), (2.73, -0.43)]], []]
...