¿Determinar valores mínimos y máximos en un dataset ráster ASCII usando Python?

12

Tengo un dataset ráster en formato ASCII. Usando Python, necesito determinar los valores miny maxdentro del conjunto de datos. Me han dicho que la información del encabezado es clave, que contiene elementos como el número de filas / columnas, el tamaño de la celda, etc.

¿No puede simplemente omitir la información del encabezado y leer todo el conjunto de datos para determinar los valores miny max?

Esto es lo que estoy tratando de hacer. Estoy omitiendo el primer par de líneas que contienen la información del encabezado e intento determinar los valores a partir de ahí. Lo siguiente es algo de lo que tengo, pero necesito alguna orientación ya que soy nuevo en 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

¿Alguna sugerencia?

kaoscify
fuente
2
¿Estás usando código abierto o pila ESRI?
oscuro

Respuestas:

12

Puedes usar numpy. Vea el ejemplo a continuación. Se puede generar una matriz enmascarada numpy teniendo en cuenta los valores sin datos. Consulte el tema de ayuda numpy para mafromtxt y 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]]

>>>

a partir de ahí, simplemente es cuestión de determinar las estadísticas que desea

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

fuente
Gracias Dan. Voy a intentar esto. ¿Hay alguna forma alternativa ... tal vez sin el módulo numpy?
kaoscify
6

Desea estadísticas de datos ráster.
Vea lo que está haciendo en la interfaz gráfica de usuario primero (para la tarea).

Luego puede usar una ventana de Python o un script .

import arcpy
arcpy.CalculateStatistics_management("c:/data/image.tif", "4", "6", "0;255;21")
Brad Nesom
fuente
Una vez que calcula las estadísticas, siempre puede acceder a las estadísticas a través de la propiedad de objeto ráster también. por ejemplo, r = arcpy.Raster ("c: /data/image.tif"), r.mean, r.minimum, r.maximum
blord-castillo
@ blord-castillo ¡Genial! No lo sabia. Gracias por el consejo :)
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
fuente
Esto es algo de lo que estaba intentando antes, pero sigo recibiendo errores cuando uso el método de división:AttributeError: 'list' object has no attribute 'split'
kaoscify
Siento que la línea en data = raster_file.readlines()[4:]realidad no funciona cuando se trata de especificar el rango. Arregle el error que estaba teniendo en el comentario anterior. Esto se hizo agregando num = data[7]en la tercera línea. Luego se dividió usando values = num.split()y pudo encontrar el máximo / mínimo, pero solo para esa línea en particular. ¿Cómo puedo encontrar el máximo / mínimo de todo el documento?
kaoscify
oh, mi error, "datos" es una lista, "líneas" es la cadena. Edité el código ... Lo probé con un archivo asc. Simplemente copie y pegue, preste atención a la sangría.
Pablo
2
Puede soltar el if check==Truebloque inicializando sus valores min / max. Deberá inicializar min en sys.float_info.max y max en sys.float_info.min.
Sasa Ivetic
3
Debe inicializar max en sys.float_info.min y min en sys.float_info.max. Que tu mínimo inicial será el mayor valor posible, y cualquier valor que compares con él será menor y, por lo tanto, se convertirá en el nuevo mínimo. Lo mismo ocurre con su valor máximo, será el valor más pequeño posible, y cualquier valor que compare será mayor, y por lo tanto, el nuevo máximo.
Sasa Ivetic
1

Si no quieres usar numpy (y realmente deberías, es perfecto para este tipo de cosas), entonces necesitarás:

  • inicialice su maximumvariable a un número negativo muy grande y su minimumvariable a un número positivo muy grande
  • divide cada línea para obtener una lista de cadenas y usa la comprensión de la lista para convertirla en una lista de flotantes
  • finalmente use algo como maximum = max(maximum, max(myfloatlist))y un equivalente para el valor mínimo.
MerseyViking
fuente
0

Acabo de hacer esto el otro día. Utilicé arcpy.RasterToNumPyArray, convertí la matriz numpy en una lista, luego recorrí mi lista a través de una comprensión de la lista para encontrar los valores mínimos y máximos.

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
fuente
no es myArray.min()/ myArray.max()más simple / más rápido?
Mike T
1
@Chad, si ya tiene la matriz numpy, entonces no hay necesidad de convertir a una lista, simplemente use las funciones min (), max (), etc. en mi hilo anterior. Como también observa, no se indicó acceso implícito a Arcpy.