การกำหนดค่า min และ max ในชุดข้อมูล raster 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 stack หรือไม่
underdark

คำตอบ:


12

คุณสามารถใช้จำนวนมาก ดูตัวอย่างด้านล่าง อาเรย์ที่สวมหน้ากาก numpy สามารถสร้างบัญชีได้โดยไม่มีค่าข้อมูล ดูหัวข้อช่วยเหลือ numpy สำหรับ 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
>>> 

ขอบคุณแดน ฉันจะลองทำดู มีทางเลือกอื่น ... อาจจะไม่มีโมดูลที่ดี?
kaoscify

6

คุณต้องการสถิติข้อมูลแรสเตอร์
ดูสิ่งที่คุณกำลังทำใน gui ก่อน (สำหรับการบ้าน)

แล้วคุณสามารถใช้หน้าต่างหลามหรือสคริปต์

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

โอ้ความผิดพลาดของฉัน "data" คือรายการ "lines" เป็นสตริง ฉันแก้ไขรหัสแล้ว ... ฉันทดสอบด้วยไฟล์ asc เพียงแค่คัดลอกและวางให้ความสนใจกับการเยื้อง
Pablo

2
คุณสามารถวางif check==Trueบล็อกโดยเริ่มต้นค่าต่ำสุด / สูงสุดของคุณ คุณจะต้องเริ่มต้นขั้นต่ำเป็น sys.float_info.max และสูงสุดเป็น sys.float_info.min
Sasa Ivetic

3
คุณต้องเริ่มต้นสูงสุดเป็น sys.float_info.min และนาทีถึง sys.float_info.max ว่าคุณเริ่มต้นนาทีของคุณจะเป็นค่าที่เป็นไปได้ที่ใหญ่ที่สุดและค่าใด ๆ ที่คุณเปรียบเทียบกับมันจะมีขนาดเล็กลงและกลายเป็นนาทีใหม่ เช่นเดียวกันกับค่าสูงสุดของคุณมันจะเป็นค่าที่เล็กที่สุดที่เป็นไปได้และค่าใด ๆ ที่คุณเปรียบเทียบกับมันจะใหญ่กว่าและทำให้ค่าสูงสุดใหม่
Sasa Ivetic

1

หากคุณไม่ต้องการใช้ numpy (และคุณควรจริง ๆ มันเหมาะสำหรับสิ่งนี้) จากนั้นคุณจะต้อง:

  • เริ่มต้นmaximumตัวแปรของคุณเป็นจำนวนลบที่มีขนาดใหญ่มากและminimumตัวแปรของคุณเป็นจำนวนบวกที่มีขนาดใหญ่มาก
  • แยกแต่ละบรรทัดเพื่อรับรายการของสตริงและใช้list comprehensionเพื่อแปลงเป็นรายการลอย
  • ในที่สุดใช้สิ่งที่ต้องการmaximum = max(maximum, max(myfloatlist))และเทียบเท่าสำหรับค่าต่ำสุด

0

ฉันเพิ่งทำสิ่งนี้ในวันอื่น ฉันใช้arcpy.RasterToNumPyArrayแปลงอาร์เรย์ numpy เป็นรายการจากนั้นวนซ้ำผ่านรายการของฉันผ่านรายการความเข้าใจเพื่อค้นหาค่า 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()เรียบง่าย / เร็วกว่านี้?
Mike T

1
@Chad หากคุณมีอาร์เรย์ numpy อยู่แล้วไม่จำเป็นต้องแปลงเป็นรายการเพียงใช้ฟังก์ชัน min (), max () ฯลฯ ในเธรดของฉันด้านบน ตามที่คุณทราบยังไม่มีการระบุถึงการเข้าถึง Arcpy
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.