Déterminer les valeurs min et max dans un jeu de données raster ASCII à l'aide de Python?

12

J'ai un jeu de données raster au format ASCII. En utilisant Python, j'ai besoin de déterminer les valeurs minet maxà l'intérieur de l'ensemble de données. On m'a dit que les informations d'en-tête sont essentielles, qui contiennent des éléments comme le nombre de lignes / colonnes, la taille des cellules, etc.

Vous ne pouvez pas simplement ignorer les informations d'en-tête et lire l'ensemble de données complet pour déterminer les valeurs minet max?

Voilà ce que j'essaie de faire. J'ignore les deux premières lignes qui contiennent les informations d'en-tête et j'essaie de déterminer les valeurs à partir de là. Ce qui suit est en quelque sorte ce que j'ai, mais j'ai besoin de quelques conseils car je suis nouveau sur Python.

raster_file = open('data.asc', 'r') # Open the file
data = raster_file.readlines()[4:] # Read the lines in the file, and skip the first six lines

for lines in data:
    print max(data) # Find the max value in data
    print min(data) # Find hte min value in data

Aucune suggestion?

kaoscify
la source
2
Utilisez-vous l'open source ou la pile ESRI?
underdark

Réponses:

12

Vous pouvez utiliser numpy. Voir l'exemple ci-dessous. Un tableau masqué numpy peut être généré en tenant compte des valeurs sans données. Voir la rubrique d'aide numpy pour mafromtxt et genfromtxt

Below is a small ascii file with a nodata value of -999

ncols          3
nrows          3
xllcorner      0
yllcorner      0
cellsize       1
NODATA_value   -999
0 1 2
-999 4 5 
6 7 8

>>> import numpy as np
>>> ascii_file = "c:/temp/Ascii_3x3_1nodata.asc"
>>> an_array = np.mafromtxt(ascii_file, 'float', '#', None, 6, None, '-999')

>>> print an_array

[[0.0 1.0 2.0]
 [-- 4.0 5.0]  
 [6.0 7.0 8.0]]

>>>

à partir de là, il s'agit simplement de déterminer les statistiques que vous souhaitez

>>> print an_array.min()
0.0
>>> print an_array.max()
8.0
>>> print an_array.mean()
4.125
>>> 

la source
Merci Dan. Je veux bien essayer. Existe-t-il un autre moyen ... peut-être sans le module numpy?
kaoscify
6

Vous voulez des statistiques de données raster.
Voyez d'abord ce que vous faites dans l'interface graphique (pour les devoirs.)

Ensuite, vous pouvez utiliser une fenêtre python ou un script .

import arcpy
arcpy.CalculateStatistics_management("c:/data/image.tif", "4", "6", "0;255;21")
Brad Nesom
la source
Une fois que vous avez calculé les statistiques, vous pouvez toujours accéder aux statistiques via la propriété d'objet raster également. par exemple r = arcpy.Raster ("c: /data/image.tif"), r.mean, r.minimum, r.maximum
blord-castillo
@ blord-castillo Cool! Je ne le savais pas. Merci pour le conseil :)
kaoscify
3
import sys

class Ascii_file(object):
    def __init__(self,file):
        self.raster_file = open(file, 'r') # Open the file
        self.max=sys.float_info.min
        self.min=sys.float_info.max
    def __minmax(self,value):
        if value>self.max:self.max=value
        if value<self.min:self.min=value
    def getMinMax(self):
        data = self.raster_file.readlines()
        data_values=data[6:]
        nodata=float(data[5].split()[1])
        for line in data_values:
            values=line.split(" ")
            for value in values:
                value=float(value)
                if value==nodata:continue
                else: self.__minmax(value)
        return self.min, self.max

if __name__=="__main__":
    myfile = Ascii_file('data.asc')
    print myfile.getMinMax()
Pablo
la source
C'est en quelque sorte ce que j'essayais plus tôt, mais je reçois toujours des erreurs lorsque j'utilise la méthode de partage:AttributeError: 'list' object has no attribute 'split'
kaoscify
J'ai l'impression que la ligne data = raster_file.readlines()[4:]ne fonctionne pas vraiment quand il s'agit de spécifier la plage. J'ai corrigé l'erreur que je rencontrais dans le commentaire précédent. Cela a été fait en ajoutant num = data[7]à la 3e ligne. Il a ensuite été divisé en utilisant values = num.split()et a pu trouver le max / min, mais uniquement pour cette ligne particulière. Comment puis-je trouver le max / min dans tout le document?
kaoscify
oh, mon erreur, "data" est une liste, "lines" est la chaîne. J'ai édité le code ... Je l'ai testé avec un fichier asc. Copiez et collez, faites attention à l'indentation.
Pablo
2
Vous pouvez supprimer le if check==Truebloc en initialisant vos valeurs min / max. Vous voudrez initialiser min en sys.float_info.max et max en sys.float_info.min.
Sasa Ivetic,
3
Vous devez initialiser max à sys.float_info.min et min à sys.float_info.max. Que vous votre min initial soit la plus grande valeur possible, et toute valeur que vous lui comparerez sera plus petite, et deviendra ainsi le nouveau min. Il en va de même avec votre valeur maximale, ce sera la plus petite valeur possible, et toute valeur que vous lui comparerez sera plus grande, et donc la nouvelle valeur max.
Sasa Ivetic,
1

Si vous ne voulez pas utiliser numpy (et vous devriez vraiment le faire, c'est parfait pour ce genre de chose), alors vous devrez:

  • initialisez votre maximumvariable à un très grand nombre négatif et votre minimumvariable à un très grand nombre positif
  • divisez chaque ligne pour obtenir une liste de chaînes et utilisez la compréhension de liste pour la convertir en une liste de flottants
  • enfin utiliser quelque chose comme maximum = max(maximum, max(myfloatlist))et un équivalent pour la valeur minimale.
MerseyViking
la source
0

Je viens de le faire l'autre jour. J'ai utilisé arcpy.RasterToNumPyArray, converti le tableau numpy en liste, puis parcouru ma liste via une compréhension de liste pour trouver les valeurs min et max.

import arcpy
import numpy
myArray = arcpy.RasterToNumPyArray(r"D:\NED_93512417\NED_93512417_3DEM_RPRJ.TIF")
p = myArray.tolist()

max_elev = max([item for sublist in p for item in sublist])
min_elev = min([item for sublist in p for item in sublist])
Chad Cooper
la source
n'est-ce pas myArray.min()/ myArray.max()plus simple / plus rapide?
Mike T
1
@Chad, si vous avez déjà le tableau numpy, alors il n'est pas nécessaire de convertir en liste, utilisez simplement les fonctions min (), max () etc. dans mon fil ci-dessus. Comme vous le constatez également, aucun accès implicite à Arcpy n'a été indiqué.