Określanie wartości minimalnych i maksymalnych w zestawie danych rastrowych ASCII przy użyciu Pythona?

12

Mam zestaw danych rastrowych w formacie ASCII. Za pomocą Pythona muszę określić wartości mini maxwewnątrz zbioru danych. Powiedziano mi, że informacja w nagłówku jest kluczowa, która zawiera takie rzeczy, jak liczba wierszy / kolumn, rozmiar komórki itp.

Czy nie możesz po prostu pominąć informacji nagłówka i przeczytać cały zestaw danych, aby określić wartości mini max?

To właśnie próbuję zrobić. Pomijam pierwsze kilka wierszy, które zawierają informacje nagłówka, i od tego momentu próbuję ustalić wartości. Poniżej znajduje się coś, co mam, ale potrzebuję wskazówek, ponieważ jestem nowy w Pythonie.

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

Jakieś sugestie?

kaoscify
źródło
2
Czy używasz stosu open source lub ESRI?
podmroku

Odpowiedzi:

12

Możesz użyć numpy. Zobacz przykład poniżej. Można wygenerować tablicę zamaskowaną numpy uwzględniającą wartości bez danych. Zobacz temat pomocy numpy dla mafromtxt i 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]]

>>>

stamtąd wystarczy po prostu ustalić odpowiednie statystyki

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

źródło
Dziękuję Dan. Spróbuję tego. Czy istnieje alternatywny sposób ... może bez modułu numpy?
kaoscify
6

Chcesz statystyki danych rastrowych.
Najpierw zobacz, co robisz w GUI (na zadanie domowe).

Następnie możesz użyć okna Pythona lub skryptu .

import arcpy
arcpy.CalculateStatistics_management("c:/data/image.tif", "4", "6", "0;255;21")
Brad Nesom
źródło
Po obliczeniu statystyk zawsze można uzyskać dostęp do statystyk za pośrednictwem właściwości obiektu rastrowego. np. r = arcpy.Raster ("c: /data/image.tif"), r.mean, r.minimum, r.maximum
blord-castillo
@ blord-castillo Cool! Nie wiedziałem tego. Dzięki za podpowiedź :)
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
źródło
Jest to coś, czego próbowałem wcześniej, ale ciągle AttributeError: 'list' object has no attribute 'split'
pojawiają
Wydaje mi się, że linia data = raster_file.readlines()[4:]faktycznie nie działa, jeśli chodzi o określenie zakresu. Naprawiłem błąd, który miałem w poprzednim komentarzu. Dokonano tego poprzez dodanie num = data[7]w 3. linii. Następnie został podzielony za pomocą values = num.split()i był w stanie znaleźć maks / min, ale tylko dla tej konkretnej linii. Jak mogę znaleźć maks./min z całego dokumentu?
kaoscify
och, mój błąd, „dane” to lista, „wiersze” to ciąg znaków. Edytowałem kod ... Przetestowałem go przy pomocy pliku asc. Wystarczy skopiować i wkleić, zwracając uwagę na wcięcie.
Pablo
2
Możesz upuścić if check==Trueblok, inicjując wartości min / maks. Będziesz chciał zainicjować min do sys.float_info.max i max do sys.float_info.min.
Sasa Ivetic
3
Musisz zainicjować max do sys.float_info.min i min do sys.float_info.max. To, że twoja początkowa min będzie największą możliwą wartością, a każda porównywana z nią wartość będzie mniejsza, a zatem stanie się nową min. To samo dotyczy wartości maksymalnej, będzie to najmniejsza możliwa wartość, a każda porównywana z nią wartość będzie większa, a zatem nowa wartość maksymalna.
Sasa Ivetic
1

Jeśli nie chcesz używać numpy (a naprawdę powinieneś, jest to idealne rozwiązanie do tego typu rzeczy), musisz:

  • zainicjuj maximumzmienną na bardzo dużą liczbę ujemną, a minimumzmienną na bardzo dużą liczbę dodatnią
  • podziel każdą linię, aby uzyskać listę ciągów, i skorzystaj ze zrozumienia listy, aby przekonwertować ją na listę liczb zmiennoprzecinkowych
  • w końcu użyj czegoś podobnego maximum = max(maximum, max(myfloatlist))i ekwiwalentu dla minimalnej wartości.
MerseyViking
źródło
0

Zrobiłem to innego dnia. Użyłem arcpy.RasterToNumPyArray, przekonwertowałem tablicę numpy na listę, a następnie iterowałem moją listę za pomocą zrozumienia listy, aby znaleźć wartości min i maks.

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
źródło
nie jest myArray.min()/ myArray.max()prostsze / szybsze?
Mike T
1
@Chad, jeśli masz już tablicę numpy, nie ma potrzeby konwertowania na listę, wystarczy użyć funkcji min (), max () itp. W moim wątku powyżej. Jak zauważasz, nie wskazano żadnego dorozumianego dostępu do Arcpy.