Визначення мінімальних та максимальних значень у растровому наборі даних ASCII за допомогою Python?


12

У мене є растровий набір даних у форматі ASCII. Використовуючи Python, мені потрібно визначити значення minта maxзначення всередині набору даних. Мені сказали, що ключовою є інформація в заголовку, яка містить такі речі, як кількість рядків / стовпців, розмір комірок тощо.

Ви не можете просто пропустити інформацію заголовка і прочитати весь набір даних, щоб визначити значення minта maxзначення?

Це те, що я намагаюся зробити. Я пропускаю перші пару рядків, які містять інформацію заголовка, і намагаюся визначити значення звідти далі. Далі йде щось про те, що я маю, але мені потрібні певні рекомендації, оскільки я новачок у 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

Будь-які пропозиції?


2
Використовуєте стек з відкритим кодом або ESRI?
underdark

Відповіді:


12

Ви можете використовувати numpy. Дивіться приклад нижче. Масивний масив може бути створений з урахуванням значень без даних. Дивіться тему довідки про numpi для mafromtxt та 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]]

>>>

звідти просто питання визначити потрібну статистику

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

Дякую Дену. Я спробую це спробувати. Чи є альтернативний спосіб ... можливо, без модуля numpy?
kaoscify

6

Ви хочете статистику растрових даних.
Спершу подивіться, що ви робите в гуї (для домашніх завдань.)

Тоді ви можете використовувати вікно пітона або сценарій .

import arcpy
arcpy.CalculateStatistics_management("c:/data/image.tif", "4", "6", "0;255;21")

Після обчислення статистики ви завжди можете отримати доступ до статистики і через властивість растрового об'єкта. наприклад, r = arcpy.Raster ("c: /data/image.tif"), r.mean, r.minimum, r.maximum
blord-castillo

@ blord-castillo Класно! Не знав цього. Дякую за пораду :)
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()

Це щось із того, що я намагався раніше, але я постійно отримую помилки, коли використовую метод розділення:AttributeError: 'list' object has no attribute 'split'
kaoscify

Я відчуваю, що лінія data = raster_file.readlines()[4:]насправді не працює, якщо мова йде про визначення діапазону. Я виправив помилку, яку мав у попередньому коментарі. Це було зроблено додаванням num = data[7]у 3-му рядку. Потім це було розділено за допомогою values = num.split()і змогло знайти макс / хв, але лише для цього конкретного рядка. Як я можу знайти макс / хв у всьому документі?
kaoscify

ой, моя помилка, "дані" - це список, "рядки" - це рядок. Я відредагував код ... Я перевірив його з файлом asc. Просто скопіюйте та вставте, зверніть увагу на відступ.
Пабло

2
Ви можете скинути if check==Trueблок, ініціалізуючи значення min / max. Ви хочете ініціалізувати min до sys.float_info.max, а max - до sys.float_info.min.
Саса Іветик

3
Ви повинні ініціалізувати max до sys.float_info.min, а min до sys.float_info.max. Що ви, ваш початковий хв, буде найбільшим можливим значенням, і будь-яке значення, яке ви порівнюєте з ним, буде меншим і, таким чином, стане новим хв. Те саме стосується і вашого максимального значення, воно буде найменшим можливим значенням, і будь-яке значення, яке ви порівняєте з ним, буде більшим, а значить, і новим макс.
Саса Іветіч

1

Якщо ви не хочете використовувати numpy (і ви справді повинні, це ідеально підходить для подібних речей), вам знадобиться:

  • ініціалізуйте свою maximumзмінну до дуже великого від’ємного числа, а вашу minimumзмінну до дуже великого додатного числа
  • розділіть кожен рядок, щоб отримати список рядків, і використовуйте розуміння списку, щоб перетворити його у список плавців
  • нарешті, використовуйте щось на зразок maximum = max(maximum, max(myfloatlist))і еквівалент для мінімального значення.

0

Я це робив днями. Я використав arcpy.RasterToNumPyArray, перетворив нумеровий масив у список, а потім повторив свій список за допомогою розуміння списку, щоб знайти значення min та 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])

не myArray.min()/ myArray.max()простіше / швидше?
Майк T

1
@Chad, якщо у вас вже є масив numpy, то немає необхідності перетворювати на список, просто використовуйте функції min (), max () тощо у моєму потоці вище. Як ви також зазначаєте, не передбачався доступ до Arcpy.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.