Xác định giá trị tối thiểu và tối đa trong bộ dữ liệu raster ASCII bằng Python?


12

Tôi có một bộ dữ liệu raster ở định dạng ASCII. Sử dụng Python, tôi cần xác định minmaxcác giá trị bên trong tập dữ liệu. Tôi đã được thông báo rằng thông tin tiêu đề là khóa, chứa những thứ như số hàng / cột, kích thước ô, v.v.

Bạn có thể đơn giản bỏ qua thông tin tiêu đề và đọc toàn bộ dữ liệu để xác định minmaxgiá trị không?

Đây là những gì tôi đang cố gắng làm. Tôi bỏ qua vài dòng đầu tiên chứa thông tin tiêu đề và cố gắng xác định các giá trị từ đó trở đi. Sau đây là những gì tôi có, nhưng cần một số hướng dẫn vì tôi chưa quen với 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

Bất kỳ đề xuất?


2
Bạn đang sử dụng ngăn xếp nguồn mở hay ESRI?
underdark

Câu trả lời:


12

Bạn có thể sử dụng numpy. Xem ví dụ dưới đây. Một mảng mặt nạ numpy có thể được tạo ra chiếm không có giá trị dữ liệu. Xem chủ đề trợ giúp numpy cho mafromtxt và 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]]

>>>

từ đó đơn giản chỉ là vấn đề xác định số liệu thống kê bạn muốn

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

Cảm ơn Dan. Tôi sẽ thử. Có một cách khác ... có thể không có mô-đun numpy?
kaoscify

6

Bạn muốn thống kê dữ liệu raster.
Xem những gì bạn đang làm trong gui đầu tiên (cho bài tập về nhà.)

Sau đó, bạn có thể sử dụng một cửa sổ python hoặc một kịch bản .

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

Khi bạn tính toán số liệu thống kê, bạn luôn có thể truy cập số liệu thống kê thông qua thuộc tính đối tượng raster. ví dụ: r = arcpy.Raster ("c: /data/image.tif"), r.mean, r.minimum, r.maximum
blord-castillo

@ blord-castillo Tuyệt! Không biết điều đó. Cảm ơn vì tiền boa :)
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()

Đây là loại những gì tôi đã thử trước đó, nhưng tôi vẫn gặp lỗi khi sử dụng phương pháp phân tách:AttributeError: 'list' object has no attribute 'split'
kaoscify

Tôi cảm thấy như dòng data = raster_file.readlines()[4:]không thực sự hoạt động khi chỉ định phạm vi. Tôi đã sửa lỗi mà tôi đã gặp trong bình luận trước. Điều này đã được thực hiện bằng cách thêm num = data[7]vào dòng thứ 3. Sau đó, nó được phân tách bằng cách sử dụng values = num.split()và có thể tìm tối đa / phút, nhưng chỉ cho dòng cụ thể đó. Làm cách nào tôi có thể tìm tối đa / phút từ toàn bộ tài liệu?
kaoscify

oh, lỗi của tôi, "dữ liệu" là một danh sách, "dòng" là chuỗi. Tôi đã chỉnh sửa mã ... Tôi đã kiểm tra nó với một tệp asc. Chỉ cần sao chép và dán, chú ý đến vết lõm.
Pablo

2
Bạn có thể thả if check==Truekhối bằng cách khởi tạo các giá trị tối thiểu / tối đa của mình. Bạn sẽ muốn khởi tạo min thành sys.float_info.max và max thành sys.float_info.min.
Sasa Ivetic

3
Bạn phải khởi tạo max thành sys.float_info.min và min thành sys.float_info.max. Rằng bạn tối thiểu ban đầu của bạn sẽ là giá trị lớn nhất có thể, và bất kỳ giá trị nào bạn so sánh với nó sẽ nhỏ hơn, và do đó trở thành min mới. Tương tự với giá trị tối đa của bạn, nó sẽ là giá trị nhỏ nhất có thể và bất kỳ giá trị nào bạn so sánh với nó sẽ lớn hơn và do đó, giá trị tối đa mới.
Sasa Ivetic

1

Nếu bạn không muốn sử dụng numpy (và bạn thực sự nên, nó hoàn hảo cho loại điều này), thì bạn sẽ cần phải:

  • khởi tạo maximumbiến của bạn thành một số âm rất lớn và minimumbiến của bạn thành một số dương rất lớn
  • tách từng dòng để có được một danh sách các chuỗi và sử dụng sự hiểu biết danh sách để chuyển đổi nó thành một danh sách các float
  • cuối cùng sử dụng một cái gì đó như maximum = max(maximum, max(myfloatlist))và tương đương với giá trị tối thiểu.

0

Tôi chỉ làm điều này vào ngày khác. Tôi đã sử dụng arcpy.RasterToNumPyArray, chuyển đổi mảng numpy thành một danh sách, sau đó lặp qua danh sách của mình thông qua việc hiểu danh sách để tìm các giá trị tối thiểu và tối đa.

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])

không myArray.min()/ myArray.max()đơn giản hơn / nhanh hơn?
Mike T

1
@Chad, nếu bạn đã có mảng numpy, thì không cần phải chuyển đổi thành danh sách, chỉ cần sử dụng các hàm min (), max () vv trong luồng của tôi ở trên. Như bạn cũng lưu ý, không có quyền truy cập ngụ ý nào đến Arcpy được chỉ định.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.