2011-12-06 11 views
5

Estoy tratando de encontrar la forma óptima (el rendimiento más rápido) para procesar datos de coordenadas y mediciones almacenados en varias matrices numpy.Procesamiento de matriz de rendimiento rápido en Numpy/Python

Necesito calcular la distancia desde cada punto de la grilla (lote, longitud, valor alt en verde en la imagen adjunta) a cada ubicación de medición (lat, lon, alt, rango desde el objetivo en gris en la imagen adjunta). Ya que hay cientos de puntos de la rejilla, y miles de rangos de medida para calcular para cada punto de la cuadrícula, me gustaría recorrer las matrices de la manera más eficiente posible

enter image description here

Estoy tratando de decidir entre cómo almacenar las medidas de LLA para la grilla y las mediciones, y luego cuál es la forma ideal de calcular el error cuadrado medio para cada punto de la grilla en función del delta entre el valor de rango medido y el rango real.

Cualquier idea sobre cómo almacenar mejor estos valores, y luego iterar a través de la cuadrícula para determinar el rango de cada medición sería muy apreciada. ¡¡¡Gracias!!!

Actualmente, estoy usando un meshgrid 2D para almacenar los valores LLA para la red

# Create a 2D Grid that will be used to store the MSE estimations 
# First, create two 1-D arrays representing the X and Y coordinates of our grid 
x_delta = abs(xmax-xmin)/gridsize_x 
y_delta = abs(ymax-ymin)/gridsize_y 
X = np.arange(xmin,xmax+x_delta,x_delta) 
Y = np.arange(ymin,ymax+y_delta,y_delta) 

# Next, pass arrays to meshgrid to return 2-D coordinate matrices from the 1-D coordinate arrays 
grid_lon, grid_lat = np.meshgrid(X, Y) 

I tienen los puntos de LLA y valores de rango de las mediciones almacenadas en una clase de medición

measurement_lon = [measurement.gps.getlon() for measurement in target_measurements] 
measurement_lat = [measurement.gps.getlat() for measurement in target_measurements] 
measurement_range = [measurement.getrange() for measurement in target_measurements] 

Clase de medición

class RangeMeasurement: 

def __init__(self, lat, lon, alt, range): 
    self.gps = GpsLocation(lat,lon,alt) 
    self.range = range 

pseudocódigo realmente malo para el cálculo de rango (iterativ e y muy lento)

for i in len(grid_lon): 
    for j in len(measurement_lat): 
    range_error += distance(grid_lon[i],grid_lat[i],measurement_lon[j],measurement_lat[j])-measurement_range[j]  
+0

Por desgracia, no se puede publicar la imagen sin embargo, ya que el usuario AMA nuevo mensaje mí si está interesado y puedo enviarle por correo electrónico la imagen de ejemplo – Alex

+2

Puede publicarlo en algún sitio para compartir imágenes y poner el enlace, de manera que uno de nosotros con suficiente reputación pueda integrarlo correctamente en la publicación. – mac

+0

Entendido, gracias por la oferta. – Alex

Respuesta

3

creo que el módulo de scipy.spatial.distance le ayudará a cabo con este problema: http://docs.scipy.org/doc/scipy/reference/spatial.distance.html

Debe almacenar sus puntos como 2-d matrices numpy con 2 columnas y N filas, donde N es la cantidad de puntos en la matriz. Para convertir su grid_lon y grid_lat a este formato, utilice

N1 = grid_lon.size 
grid_point_array = np.hstack([grid_lon.reshape((N1,1)), grid_lat.reshape((N1,1))]) 

Esto toma todos los valores en grid_lon, que están dispuestos en una matriz rectangular que tiene la misma forma que la rejilla, y los pone en una matriz con una columna y N filas. Hace lo mismo para grid_lat. Las dos matrices anchas de una columna se combinan para crear una matriz de dos columnas.

Un método similar se puede utilizar para convertir sus datos de medición:

N2 = len(measurement_lon) 
measurment_data_array = np.hstack([np.array(measurement_lon).reshape((N2,1)), 
    np.array(measurement_lat).reshape((N2,1))]) 

Una vez que los datos están en este formato, usted puede encontrar fácilmente las distancias entre cada par de puntos con scipy.spatial.distance:

d = scipy.spatial.distance.cdist(grid_point_array, measurement_data_array, 'euclidean') 

d será una matriz con N1 filas y columnas N2, yd [i, j] será la distancia entre el punto de la cuadrícula iy el punto de medición j.

EDITAR Gracias por aclarar el error de rango. Suena como un proyecto interesante.Esto debe darle el punto de la cuadrícula con el error al cuadrado más pequeño acumulada:

measurement_range_array = np.array(measurement_range) 
flat_grid_idx = pow(measurement_range_array-d,2).sum(1).argmin() 

Esto se aprovecha de broadcasting para obtener la diferencia entre el rango de medida de un punto y su distancia desde cada punto de la cuadrícula. A continuación, se suman todos los errores de un punto de cuadrícula determinado, y el conjunto 1-D resultante debe ser el error acumulado que está buscando. argmin() se llama para encontrar la posición del valor más pequeño. Para obtener la x e y las coordenadas de cuadrícula del índice aplanado, utilice

grid_x = flat_grid_idx % gridsize_x 
grid_y = flat_grid_idx // gridsize_x 

(El // es la división entera.)

+0

Gracias, esto funcionó muy bien para mí. Convertí los puntos de la malla LLA en posiciones ECEF (Earth Centered Earth Fixed) para resolver en 3D y también para que la salida estuviera en metros cuando se ejecuta scipy.spatial.cistance.cdist en las coordenadas XYZ. – Alex

+0

Para explicar el rango "Real" frente a "Calculado", cada una de las mediciones (en verde arriba) tiene un LLA y un rango estimado para el transmisor. El propósito de la cuadrícula de cálculo es encontrar el dispositivo transmisor, por lo que recorro cada punto de la cuadrícula y encuentro el error acumulado de todas las mediciones en cada punto particular. el punto con la menor cantidad de error debe ser el más cercano a la posición objetivo. – Alex

Cuestiones relacionadas