2017-09-03 2 views
1

J'ai des données d'emplacements d'animaux (X, Y, Z) et j'ai des données d'arbre (X, Y, Z). J'ai besoin de tirer toutes les entrées d'arbres XYZ qui se produisent autour des emplacements d'animaux - donc j'ai besoin de comparer un tableau numpy contenant des emplacements d'animaux xyz à un tableau numpy contenant des emplacements ponctuels x y z d'arbres dans la même zone. Je veux tirer tous les arbres xyz dans un rayon de 4 unités et écrire une fonction pour le faire. Mais il ne fait pas que tirer les arbres autour des emplacements des animaux. il imprime juste tous les arbres possibles. Comment puis-je tirer seulement les arbres autour des points d'animaux et ensuite les mettre dans un fichier .txt que je peux utiliser dans un autre programme? Je suis nouveau à la programmation et toute aide que je peux obtenir est grandement appréciée.Python: Comment puis-je comparer des données entières dans un tableau numpy à des données entières dans un autre tableau numpy et lire les résultats dans un fichier .txt?

ce qui suit est mon code aveC#descriptions:

#using array instead of dataframe 
import numpy as np 
from laspy.file import File 

#load and consolidate Veg Point Coordinates into one array 
VegList = sorted(glob.glob('/Users/sophiathompson/Desktop/copys/Clips/*.las')) 
VegListCoords = [] 
for f in VegList: 
    print(f) 
    Veg= File(filename = f, mode = "r") # Open the file # Eventually, this  will need to be the actual .laz files 
    VegListCoords.append(np.vstack((Veg.x, Veg.y, Veg.z)).transpose()) 
    print (VegListCoords) 
    XYZVegComplete = np.concatenate((VegListCoords), axis = 0) 

#Load animal point locations (x, y, z .csv file) from clip 240967 into array 
Animal240967 = np.loadtxt(fname='/Users/ST/Desktop/copys/CatTXTfiles/240967_CatsFt.csv', delimiter =',') 

#Use to find all vegetation heights in a 4 unit diameter of each animal point (animalx, animaly). #'d out lines of code are my attempts to make something work 
def near_Animal(animalx, animaly): 
    for x, y, z in XYZVegComplete: 
     r=2 #xy coordinates in ft 
     PointsNearAnml = [] 
     if (x-animalx)**2 + (y-animaly)**2 >= r**2: 
      PracticeTxt=open("/Users/ST/Desktop/practicefilecreate.txt", "w") 
      print (x, y, z) 
      #print (x, y, z) >> PracticeTxt, x, y, z 
      #PracticeTxt.write('%d %d %d \n' % Points) 
      #PracticeTxt.write('%d %d %d \n' % x y z) 
      #Points= (x, y, z) 
      #with open("/Users/sophiathompson/Desktop/practicefilecreate.txt", "w") as PracticeTxt: 
      #print >> PracticeTxt, Points 
      #PracticeTxt.close 
#Use to call near_Animal: gather Veg Points based on proximity to animal  points (using arrays)- 
for animalx, animaly in Animal240967: 
    near_Animal(animalx, animaly) 
+0

Ce n'est pas facile de travailler avec le code que vous avez fourni. Envisagez de créer un [Exemple minimum, complet et vérifiable] (https://stackoverflow.com/help/mcve), avec des exemples de données représentatifs et une sortie attendue. Vous aurez plus de chances d'obtenir une meilleure réponse, plus rapidement, de cette façon. –

Répondre

0

Vous voulez en fait deux fonctions différentes selon que vous mesurez dans un ensemble ou entre les séries. Voici une fonction qui fait les deux, et une explication de ce qu'il fait:

from scipy.spatial.distance import pdist, cdist 
def near_fn(*args, dist = 2., outfile = "practicefilecreate.txt"): 
    if len(args) == 1: #within a set, i.e. `Animal240967` 
     coords = args[0] 
     i, j = np.triu_indices(coords.size, 1) 
     mask = pdist(coords, 'euclidean') < dist 
     k = np.unique(np.r_[i[mask], j[mask]]) 
     np.savetxt(coords[k], outfile, delimiter = ',') #or whatever you want 
    elif len(args) == 2: # between sets i.e. `XYZVegComplete` and `Animal240967` 
     coords_ind, coords_dep = args 
     k = np.any(cdist(coords_ind, coords_dep, 'euclidean') < dist, axis = 1) 
     np.savetxt(coords_ind[k], outfile, delimiter = ',') #or whatever you want 
    else: 
     assert False, "Too many inputs" 

Ce que ceci:

  1. pdist trouve la distance entre les éléments d'un ensemble, mais ne trouve que le triangle supérieur droit de valeurs (puisque la distance entre a->b est la même que b->a, et la distance a-> est toujours 0). Ceci est un tableau 1-d, qui correspond aux emplacements donnés par triu_indices. Trouver les distances inférieures à votre seuil (pdist < dist), plan que les indices (k = i[...]) et écrire les coordonnées correspondant à ces indices de disque (np.savetxt(coords[k] . . .))

  2. cdist trouve la distance entre les deux ensembles, en tant que 2-d matrice. Trouvez les éléments moins que votre seuil (cdist(ind, dep, . . .) < dist), trouver une colonne avec un True en elle (k = np.any(. . . , axis = 1)) et encore une fois, écrire tous les coords sur le disque (np.savetxt(ind[k] . . .))

Si vous avez beaucoup de valeurs, vous souhaiterez peut-être utiliser un scipy.spatial.KDTree à la place

from scipy.spatial import KDTree 
def kd_near_fn(*args, dist = 2., outfile = "practicefilecreate.txt"): 
    trees = [KDTree(arg) for arg in args] 
    if len(trees) == 1: 
     i, j = trees[0].query_pairs(dist) 
     k = np.unique(np.r_[i, j]) 
    elif len(trees) == 2: 
     queries = trees[0].query_ball_tree(trees[1], dist) 
     k = np.array([len(query) > 0 for query in queries]) 
    else: 
     assert False, "too many inputs" 
    np.savetxt(args[0][k], outfile, delimiter = ',') 
+0

Daniel F merci beaucoup pour cette réponse. J'apprécie grandement la ventilation et les descriptions de ce que chaque étape fait que vous avez inclus. C'était incroyablement éducatif pour moi comme une nouvelle personne à la programmation informatique – SSThompson

+0

N'hésitez pas à upvote et vérifier la réponse plus utile alors :) –

+0

J'ai essayé d'utiliser le KDTree mais je n'ai pas réussi à le faire fonctionner. Je ne sais pas où je mets mes points d'animaux. Est-ce que je les traite comme un argument dans les arguments KDTree? par exemple. en définissant def_kd_near_fn (* args ..... devrais-je définir animalx, animaly ici?) puis les référencer dans les arbres = [KDTree (arg-animalx, animaly] et ensuite les paires i, j sont liées au X, Y paires pour le fichier de végétation que j'essaye de tirer d'après les paires AnimalXY – SSThompson