Determinando valores mínimo e máximo em um conjunto de dados raster ASCII usando Python?

12

Eu tenho um conjunto de dados raster no formato ASCII. Usando Python, preciso determinar os valores mine maxdentro do conjunto de dados. Foi-me dito que as informações do cabeçalho são essenciais, que contêm itens como número de linhas / colunas, tamanho da célula e etc.

Você não pode simplesmente pular as informações do cabeçalho e ler o conjunto de dados inteiro para determinar os valores mine max?

É isso que estou tentando fazer. Estou pulando as duas primeiras linhas que contêm as informações do cabeçalho e tentando determinar os valores a partir daí. A seguir, é uma espécie do que tenho, mas preciso de algumas orientações, pois sou novo no 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

Alguma sugestão?

kaoscify
fonte
2
Você está usando código aberto ou pilha ESRI?
underdark

Respostas:

12

Você pode usar numpy. Veja o exemplo abaixo. Uma matriz mascarada numpy pode ser gerada, contabilizando os valores sem dados. Consulte o tópico de ajuda numpy para mafromtxt e 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 daí, é simplesmente uma questão de determinar as estatísticas que você deseja

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

fonte
Obrigado Dan. Vou tentar. Existe uma maneira alternativa ... talvez sem o módulo numpy?
kaoscify
6

Você deseja estatísticas de dados raster.
Veja o que você está fazendo na GUI primeiro (para trabalhos de casa).

Então você pode usar uma janela python ou um script .

import arcpy
arcpy.CalculateStatistics_management("c:/data/image.tif", "4", "6", "0;255;21")
Brad Nesom
fonte
Depois de calcular as estatísticas, você também pode acessar as estatísticas por meio da propriedade do objeto raster. por exemplo, R = arcpy.Raster ( "c: /data/image.tif"), r.mean, r.minimum, r.maximum
blord-Castillo
@ castor-de-espada Legal! Não sabia disso. Obrigado pela dica :)
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
fonte
Esta é uma espécie de que eu estava tentando mais cedo, mas eu continuo recebendo erros quando eu uso o método split:AttributeError: 'list' object has no attribute 'split'
kaoscify
Eu sinto que a linha data = raster_file.readlines()[4:]realmente não funciona quando se trata de especificar o intervalo. Corrigi o erro que estava tendo no comentário anterior. Isso foi feito adicionando num = data[7]a terceira linha. Ele foi dividido usando values = num.split()e conseguiu encontrar o máximo / min, mas apenas para essa linha específica. Como posso encontrar o máximo / min de todo o documento?
kaoscify
oh, meu erro, "dados" é uma lista, "linhas" é a string. Eu editei o código ... Testei-o com um arquivo asc. Basta copiar e colar, preste atenção ao recuo.
26611 Pablo
2
Você pode eliminar o if check==Truebloco inicializando seus valores mínimo / máximo. Você deseja inicializar min para sys.float_info.max e max para sys.float_info.min.
Sasa Ivetic
3
Você deve inicializar max para sys.float_info.min e min para sys.float_info.max. Que o seu min inicial será o maior valor possível e qualquer valor comparado a ele será menor e, assim, se tornará o novo min. O mesmo vale para o seu valor máximo, será o menor valor possível e qualquer valor que você comparar será maior e, portanto, o novo valor máx.
Sasa Ivetic
1

Se você não deseja usar o numpy (e realmente deve, é perfeito para esse tipo de coisa), será necessário:

  • inicialize sua maximumvariável para um número negativo muito grande e sua minimumvariável para um número positivo muito grande
  • divida cada linha para obter uma lista de seqüências de caracteres e use a compreensão da lista para convertê-la em uma lista de flutuadores
  • finalmente use algo como maximum = max(maximum, max(myfloatlist))e um equivalente para o valor mínimo.
MerseyViking
fonte
0

Eu fiz isso outro dia. Eu usei arcpy.RasterToNumPyArray, converti a matriz numpy em uma lista e, em seguida, iteramos na minha lista por meio de uma compreensão da lista para encontrar os valores mínimo e máximo.

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
fonte
não é myArray.min()/ myArray.max()mais simples / mais rápido?
Mike T
1
@ Chad, se você já possui a matriz numpy, não há necessidade de converter para uma lista, basta usar as funções min (), max () etc na minha discussão acima. Como você também observa, nenhum acesso implícito ao Arcpy foi indicado.