2016-03-24 20 views
0

Mein Problem wie das Problem in dem Thread ist Finding index of nearest point in numpy arrays of x and y coordinates, aber es wird erweitert:Finding nächste xy-Punkt in numpy Array und zweitnächste mit Bedingung

Zur besseren Visualisierung ist hier ein Bild (manipuliertes Bild, original aus: 112BKS durch - Eigenen WerkOriginal graph/Daten von [.. ..?], CC BY-SA 3.0, link to page): source: Von 112BKS - Eigenes WerkOriginal graph/Data from [.. ? ..], CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=5949185

Auf der einer Seite gibt es eine Reihe datafield. Es besteht aus einem Nummernfeld mit Elementen [value x y]. Das sind die dünnen blauen Linien mit den Zahlen (sie sind die value). Auf der anderen Seite befindet sich das Array orangeline in einem Array mit Elementen [x y].

Was ich tun möchte, ist die value von Elementen in orangeline zu berechnen.
Ich habe ein konkretes Element von orangeline mit dem grünen Kreis visualisiert. Der Wert dafür kann ich mit den beiden Elementen datafield interpolieren, visualisiert mit den Dreiecken. Als Ergebnis erhalte ich für den grünen Kreis mit einem value zwischen 225 und 230.

Erster Schritt:
für jedes Element findet in orangeline das nächste Element in datafield.
(. In dem Beispiel, das das rosae Dreieck)

Zweiter Schritt:
für jedes Element findet in ‚orange‘ nächstgelegenen Elemente in datafield aber mit einer anderen value als dem aus dem ersten Schritt.
(In dem Beispiel, das die braune Dreieck ist.)

Dritter Schritt: die value in orangeline für jedes Element Interpolation aus diesen beiden Werten gegründet und die Abstände zu diesen Elementen.

Erster Schritt kann mit

mytree = scipy.spatial.cKDTree(datafield[:, 1:3]) 
dist1, indexes1 = mytree.query(orangeline) 

gelöst wird aber jetzt weiß ich nicht, wie das Datenfeld für den zweiten Schritt zu filtern. Gibt es eine Lösung?

+0

Haben Sie [mit 'griddata'] (http://stackoverflow.com/a/3867302/190597) in Erwägung gezogen,' datafield's Werte zu 'zu interpolieren Orangenlinie? – unutbu

Antwort

0

Mit Hilfe von @unutbu 's Kommentar fand ich diese Lösung, die ziemlich gut auch in den Fällen funktioniert, in denen die orangeline nicht durch das Feld geht.

Hier sind die Funktionen für das Netz:

import matplotlib.mlab as mlab 
import numpy as np 
import scipy 

def define_grid(rawdata): 
    xmin, xmax = np.amin(rawdata[:, 1]), np.amax(rawdata[:,1]) 
    ymin, ymax = np.amin(rawdata[:, 2]), np.amax(rawdata[:,2]) 

    x, y, z = rawdata[:, 1], rawdata[:, 2], rawdata[:, 0] 

    # Size of regular grid 
    ny, nx = (ymax - ymin), (xmax - xmin) 

    # Generate a regular grid to interpolate the data. 
    xi = np.linspace(xmin, xmax, nx) 
    yi = np.linspace(ymin, ymax, ny) 
    xi, yi = np.meshgrid(xi, yi) 

    # Interpolate using delaunay triangularization 
    zi = mlab.griddata(x,y,z,xi,yi) 
    return xi, yi, zi 

def grid_as_array(xi,yi,zi): 
    xi_flat, yi_flat, zi_flat = np.ravel(xi), np.ravel(yi), np.ravel(zi) 

    # reduce arrays for faster calculation, take only every second element 
    xi_red, yi_red, zi_red = xi_flat[1::2], yi_flat[1::2], zi_flat[1::2] 

    # stack to array with elements [x y z], but there are z values that are 'nan' 
    xyz_with_nan = np.hstack((xi_red[:, np.newaxis], yi_red[:, np.newaxis], 
           zi_red[:, np.newaxis])) 

    # sort out those elements with 'nan' 
    xyz = xyz_with_nan[~np.isnan(xyz_with_nan).any(axis=1)] 
    return xyz 

Eine weitere Funktion den nächsten Punkt aus dem Netz für die Werte von orange zu finden:

def closest_node(points, datafield): 
    mytree = scipy.spatial.cKDTree(datafield) 
    dist, indexes = mytree.query(points) 
    return indexes 

Und nun der Code:

# use function to create from the raw data an interpolated datafield 
xi, yi, zi = define_grid(datafield) 

# rearrange those values to bring them in the form of an array with [x y z] 
xyz = grid_as_array(xi, yi, zi)  

# search closest values from grid for the points of the orangeline 
# orangeline_xy is the array with elements [x y] 
indexes = self.closest_node(orangeline_xy, xyz[:,0:2]) 

# take z values from the grid which we found before 
orangeline_z = xyz[indexes, 2] 

# add those z values to the points of the orangeline 
orangeline_xyz = np.hstack((orangeline_xy,orangeline_z[:, np.newaxis]))