Постройте триангуляцию Делани, сгруппированную по значению

#python #pandas #delaunay

#python #панды #делоне

Вопрос:

Я пытаюсь построить триангуляцию Делоне из pandas df. Я надеюсь сгруппировать точки по Time . В настоящее время я получаю сообщение об ошибке при попытке построить точку с первой временной точки.

 QhullError: QH6214 qhull input error: not enough points(2) to construct initial simplex (need 6)

While executing:  | qhull d Q12 Qt Qc Qz Qbb
Options selected for Qhull 2019.1.r 2019/06/21:
  run-id 768388270  delaunay  Q12-allow-wide  Qtriangulate  Qcoplanar-keep
  Qz-infinity-point  Qbbound-last  _pre-merge  _zero-centrum  Qinterior-keep
  _maxoutside  0
  

Похоже, что он передает только эти два массива как отдельные точки.

 import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial import Delaunay

df = pd.DataFrame({
    'Time' : [1,1,1,1,2,2,2,2],                   
    'A_X' : [5, 5, 6, 6, 4, 3, 3, 4], 
    'A_Y' : [5, 6, 6, 5, 5, 6, 5, 6],                         
        })

fig, ax = plt.subplots(figsize = (6,6))
ax.set_xlim(0,10)
ax.set_ylim(0,10)
ax.grid(False)

points_x1 = df.groupby("Time")["A_X"].agg(list).tolist()
points_y1 = df.groupby("Time")["A_Y"].agg(list).tolist()

points = list(zip(points_x1, points_y1))

tri = Delaunay(points[0])

#plot triangulation
plt.triplot(points[:,0], points[:,1], tri.simplices)
plt.plot(points[:,0], points[:,1], 'o')
  

Комментарии:

1. Выполняется ли этот фактический код? Где находятся points_x1 и points_y1 установлены?

Ответ №1:

Вы можете воспользоваться методом apply, который позволяет выполнять операции с сериями.

 def make_points(x):
    return np.array(list(zip(x['A_X'], x['A_Y'])))

c = df.groupby("Time").apply(make_points)
  

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

 Time
1    [[5, 5], [5, 6], [6, 6], [6, 5]]
2    [[4, 5], [3, 6], [3, 5], [4, 6]]
dtype: object
  

Наконец, достаточно вычислить триангуляцию Делоне для каждого временного интервала и построить ее:

 fig, axe = plt.subplots()
for p in c:
    tri = Delaunay(p)
    axe.triplot(*p.T, tri.simplices)
  

введите описание изображения здесь

Вы даже можете сделать это за один вызов:

 def make_triangulation(x):
    return Delaunay(np.array(list(zip(x['A_X'], x['A_Y']))))

c = df.groupby("Time").apply(make_triangulation)

fig, axe = plt.subplots()
for tri in c:
    axe.triplot(*tri.points.T, tri.simplices)