Bestimmen von Min- und Max-Werten in einem ASCII-Raster-Dataset mit Python?

12

Ich habe ein Raster-Dataset im ASCII-Format. Mit Python muss ich die Werte minund maxim Dataset ermitteln. Mir wurde gesagt, dass die Kopfzeileninformationen der Schlüssel sind, der Dinge wie Anzahl der Zeilen / Spalten, Zellengröße usw. enthält.

Können Sie nicht einfach die Header-Informationen überspringen und den gesamten Datensatz lesen, um die Werte minund zu bestimmen max?

Das versuche ich zu tun. Ich überspringe die ersten Zeilen, die die Header-Informationen enthalten, und versuche von da an, die Werte zu ermitteln. Das Folgende ist eine Art von dem, was ich habe, aber ich brauche eine Anleitung, da ich neu in Python bin.

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

Irgendwelche Vorschläge?

kaoscify
quelle
2
Verwenden Sie Open Source oder ESRI Stack?
Underdunkel

Antworten:

12

Sie können numpy verwenden. Siehe folgendes Beispiel. Ein numpy maskiertes Array kann unter Berücksichtigung der No-Data-Werte generiert werden. Siehe das Hilfethema zu Numpy für mafromtxt und 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]]

>>>

Von dort aus müssen Sie lediglich die gewünschten Statistiken ermitteln

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

quelle
Vielen Dank, Dan. Ich werde es versuchen. Gibt es eine Alternative ... vielleicht ohne das Numpy-Modul?
Kaoscify
6

Sie möchten eine Rasterdatenstatistik.
Sehen Sie zuerst, was Sie in der Benutzeroberfläche tun (für Hausaufgaben).

Dann können Sie ein Python-Fenster oder ein Skript verwenden .

import arcpy
arcpy.CalculateStatistics_management("c:/data/image.tif", "4", "6", "0;255;21")
Brad Nesom
quelle
Sobald Sie die Statistiken berechnet haben, können Sie auch über die Raster-Objekteigenschaft auf die Statistiken zugreifen. zB r = arcpy.Raster ("c: /data/image.tif"), r.mean, r.minimum, r.maximum
blord-castillo
@ Blord-Castillo Cool! Wusste das nicht. Vielen Dank für den Tipp :)
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
quelle
Dies ist eine Art, was ich früher versucht habe, aber ich AttributeError: 'list' object has no attribute 'split'
bekomme
Ich habe das Gefühl, dass die Leitung data = raster_file.readlines()[4:]nicht funktioniert, wenn es um die Angabe des Bereichs geht. Ich habe den Fehler behoben, den ich im vorherigen Kommentar hatte. Dies erfolgte durch Hinzufügen num = data[7]in der 3. Zeile. Es wurde dann mit aufgeteilt values = num.split()und konnte die max / min finden, aber nur für diese bestimmte Zeile. Wie kann ich die maximale / minimale Anzahl aus dem gesamten Dokument ermitteln?
Kaoscify
Oh, mein Fehler, "Daten" ist eine Liste, "Zeilen" ist die Zeichenfolge. Ich habe den Code bearbeitet ... Ich habe ihn mit einer Asc-Datei getestet. Einfach kopieren und einfügen, Einrückung beachten.
Pablo
2
Sie können den if check==TrueBlock löschen, indem Sie Ihre Min / Max-Werte initialisieren. Sie möchten min auf sys.float_info.max und max auf sys.float_info.min initialisieren.
Sasa Ivetic
3
Sie müssen max auf sys.float_info.min und min auf sys.float_info.max initialisieren. Dass Sie Ihre anfängliche min der größtmögliche Wert ist und jeder Wert, den Sie damit vergleichen, kleiner wird und somit die neue min wird. Gleiches gilt für Ihren Maximalwert, er ist der kleinstmögliche Wert, und jeder Wert, den Sie damit vergleichen, ist größer, und damit der neue Maximalwert.
Sasa Ivetic
1

Wenn Sie Numpy nicht verwenden möchten (und das sollten Sie wirklich, es ist perfekt für diese Art von Dingen), dann müssen Sie Folgendes tun:

  • Initialisieren Sie Ihre maximumVariable mit einer sehr großen negativen Zahl und Ihre minimumVariable mit einer sehr großen positiven Zahl
  • Teilen Sie jede Zeile, um eine Liste mit Zeichenfolgen zu erhalten, und verwenden Sie das Listenverständnis , um sie in eine Liste mit Gleitkommazahlen zu konvertieren
  • Verwenden Sie schließlich so etwas wie maximum = max(maximum, max(myfloatlist))und ein Äquivalent für den Mindestwert.
MerseyViking
quelle
0

Ich habe das neulich getan. Ich habe arcpy.RasterToNumPyArraydas Numpy-Array verwendet, in eine Liste konvertiert und dann über ein Listenverständnis durch meine Liste iteriert, um die Min- und Max-Werte zu finden.

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
quelle
ist nicht myArray.min()/ myArray.max()einfacher / schneller?
Mike T
1
@Chad, wenn Sie bereits das Numpy-Array haben, müssen Sie es nicht in eine Liste konvertieren. Verwenden Sie einfach die Funktionen min (), max () usw. in meinem obigen Thread. Wie Sie auch bemerken, wurde kein impliziter Zugriff auf Arcpy angegeben.