Определение минимальных и максимальных значений в наборе растровых данных 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

Какие-либо предложения?

kaoscify
источник
2
Вы используете открытый код или стек ESRI?
Подземье

Ответы:

12

Вы можете использовать NumPy. Смотрите пример ниже. Может быть сгенерирован пустой массив с учетом значений данных. Смотрите раздел справки numy для 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

Вы хотите статистику растровых данных.
Сначала посмотрите, что вы делаете в графическом интерфейсе (для домашней работы.)

Тогда вы можете использовать окно Python или скрипт .

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()
Pablo
источник
Это то, что я пробовал ранее, но я продолжаю получать ошибки, когда использую метод split: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 для 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))и эквивалент для минимального значения.
MerseyViking
источник
0

Я только что сделал это на днях. Я использовал arcpy.RasterToNumPyArray, преобразовал массив NumPy в список, а затем перебрал свой список через понимание списка, чтобы найти минимальное и максимальное значения.

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()проще / быстрее?
Майк Т
1
@Chad, если у вас уже есть массив numpy, нет необходимости преобразовывать его в список, просто используйте функции min (), max () и т. Д. В моей ветке выше. Как вы также заметили, подразумеваемый доступ к Arcpy не был указан.