Tengo una trama de datos con x
, y
las coordenadas de algunos puntos. Cada punto (par de coordenadas) también está marcado con una bandera Verdadero / Falso:
xs = [1,3,7,5,4,6,2,8,9,0]
ys = [0,7,4,5,2,6,9,1,3,8]
flags = [True,False,False,False,True,True,False,True,True,True]
df = pd.DataFrame({'x':xs, 'y':ys,'flag':flags})
x y flag
0 1 0 True
1 3 7 False
2 7 4 False
3 5 5 False
4 4 2 True
5 6 6 True
6 2 9 False
7 8 1 True
8 9 3 True
9 0 8 True
Lo que reducir la función se puede utilizar para calcular distancias totales 2:
1) Distancia total para las rutas que comienzan con un punto justo después del punto Verdadero Falso o con un primer punto que es cierto que incluya todos los puntos verdaderos y terminar con un punto falso o al final de todos los puntos
2) La distancia total para las rutas que comienzan con un punto justo después Falso Verdadero o punto con un primer punto que es falso, incluyen todos los puntos falsos y terminan con un punto Verdadero o al final de todos los puntos
En este ejemplo, las secciones siguientes aparatos necesitan ser suman para obtener distancias totales:
1) Route built from True points:
(1,0) - (3,7)
---
(4,2) - (6,6)
(6,6) - (2,9)
---
(8,1) - (9,3)
(9,3) - (0,8)
2) Route built from False points:
(3,7) - (7,4)
(7,4) - (5,5)
(5,5) - (4,2)
---
(2,9) - (8,1)
Así, por ejemplo, con los siguientes puntos:
points = [((1,0),(3,7)), ((4,2),(6,6)), ((6,6),(2,9)),
((8,1),(9,3)), ((9,3),(0,8))]
# Compute distance between two points:
def distance(x1,y1,x2,y2):
return math.sqrt((x2-x1)**2 + (y2-y1)**2)
Distancia total:
total_distance = 0
for t in points:
total_distance += distance(t[0][0],t[0][1], t[1][0],t[1][1])
print(total_distance)
29.283943962766887
Cómo calcular las distancias con una función de reducir, no usar pandas.DataFrame.iterrows
?
En primer lugar se puede calcular la distancia de una manera vectorizar con shift
:
df['dist'] = np.sqrt((df['x']-df['x'].shift(-1))**2 + (df['y']-df['y'].shift(-1))**2)
a continuación, puede crear una máscara para cumplir con la condición verdadera cumsum
y diff
en la bandera de la columna:
mask_true = df['flag'].cumsum().diff().fillna(df['flag']).gt(0)
# now use loc to select these rows and the dist column plus sum
print (df.loc[mask_true,'dist'].sum())
# 29.283943962766887
para la condición falsa, entonces creo que es la complementaria, por lo que se obtiene:
print (df.loc[~mask_true,'dist'].sum())
# 20.39834563766817
EDIT: a veces, solución más fácil no viene primero, pero en realidad, mask_true
es df['flag']
así que una vez que haya creado el dist columna, puede hacerlo directamente:
print (df.loc[df['flag'],'dist'].sum())
# 29.283943962766887
print (df.loc[~df['flag'],'dist'].sum())
# 20.39834563766817