Python 柵格資料處理教程(二)

姜颢睿發表於2024-08-14

本文將介紹透過 ArcGIS Pro 的 Python 模組(arcpy)對柵格資料進行柵格計算及資料統計的方法。

1 資料來源及介紹

本文使用的資料為國家青藏高原科學資料中心的 中國1km解析度逐月降水量資料集基礎上透過《Python 柵格資料處理教程(一)》中的方法提取出的吉林省範圍降水量資料。該資料降水量單位為 0.1 mm,本文透過柵格計算器將資料單位批次轉換為 mm。根據各月份降水量疊加生成年降水量柵格及多年平均降水量柵格,同時統計歷年降水量資料資訊,並整理為 Excel 表。

2 示例程式碼

2.1 降水量單位轉換

import os
import arcpy
from arcpy import sa
from tqdm import tqdm   # 進度條工具,需自行安裝

# 設定工作空間
arcpy.env.workspace = "Pre_Jilin.gdb"

# 如果在程式碼同級資料夾中沒有結果資料庫,則建立該資料庫
if "Pre_Jilin1.gdb" not in os.listdir("."):
    print("即將為您建立用於儲存結果柵格的檔案地理資料庫(Pre_Jilin1.gdb)……")
    arcpy.CreateFileGDB_management(".", "Pre_Jilin1")
    print("資料庫建立完成!")

# 遍歷工作空間內所有柵格資料
for raster in tqdm(arcpy.ListRasters()):
    # 透過柵格計算器將柵格值單位轉換為 mm,並儲存到結果資料庫
    sa.RasterCalculator([raster], [raster], f"{raster} * 0.1").save(f"Pre_Jilin1.gdb/{raster}")
print("計算完成!")

柵格資料轉換前如下所示:

image

柵格單位轉換後如下所示:

image

2.2 根據各月份降水量生成年降水量柵格

import os
import arcpy
from arcpy import sa
from tqdm import tqdm

# 設定工作空間
arcpy.env.workspace = "Pre_Jilin1.gdb"

# 建立柵格檔案字典,以年份為鍵,值為該年份對應的各月份降水量柵格列表
file_dict = dict()
for raster in arcpy.ListRasters():
    # [4:8] 代表年份位於柵格資料名中的位置,需根據情況自行調整
    if raster[4:8] not in file_dict:
        file_dict[raster[4:8]] = [raster]
    else:
        file_dict[raster[4:8]].append(raster)

# 如果在程式碼同級資料夾中沒有結果資料庫,則建立該資料庫
if "Pre_Jilin_Year.gdb" not in os.listdir("."):
    print("即將為您建立用於儲存結果柵格的檔案地理資料庫(Pre_Jilin_Year.gdb)……")
    arcpy.CreateFileGDB_management(".", "Pre_Jilin_Year")
    print("資料庫建立完成!")

# 定義變數名,並構建代數表示式,以對輸入柵格執行空間分析
# 以 a-l 代表12個月份的降水量柵格,求全年總降水量
input_names = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"]
expression = "a + b + c + d + e + f + g + h + i + j + k + l"

# 遍歷柵格檔案字典
for year in tqdm(file_dict):
    # 提取歷年降水量柵格,透過柵格計算器生成年降水量柵格,並儲存到結果資料庫中
    sa.RasterCalculator(file_dict[year], input_names, expression).save(f"Pre_Jilin_Year.gdb/Pre_{year}")
print("計算完成!")

2023年吉林省年降水量柵格如下圖所示:

image

2.3 統計研究區年降水量的最值、均值、標準差等資訊

import os
import arcpy
from arcpy import sa
from tqdm import tqdm

# 設定工作空間
arcpy.env.workspace = "Pre_Jilin_Year.gdb"

# 如果在程式碼同級資料夾中沒有結果資料庫,則建立該資料庫
if "Pre_Jilin_Year_Info.gdb" not in os.listdir("."):
    print("即將為您建立用於儲存結果柵格的檔案地理資料庫(Pre_Jilin_Year_Info.gdb)……")
    arcpy.CreateFileGDB_management(".", "Pre_Jilin_Year_Info")
    print("資料庫建立完成!")

# 遍歷工作空間內所有柵格資料
for raster in tqdm(arcpy.ListRasters()):
    # 統計吉林省範圍內年降水量的最值、均值、標準差等資訊,並以表格的形式儲存到結果資料庫中
    sa.ZonalStatisticsAsTable("Data/Jilin.shp", "FID", raster, f"Pre_Jilin_Year_Info.gdb/{raster}")
print("統計完成!")

2.4 將統計資訊表格匯出為 txt 文字檔案

import os
import arcpy
from tqdm import tqdm

arcpy.env.workspace = "Pre_Jilin_Year_Info.gdb"

# 如果在程式碼同級資料夾中沒有結果資料夾,則建立該資料夾
if "Pre_Jilin_Year_Table" not in os.listdir("."):
    print("即將為您建立用於儲存轉換結果的資料夾(Pre_Jilin_Year_Table)……")
    os.mkdir("Pre_Jilin_Year_Table")
    print("資料夾建立完成!")

# 遍歷工作空間內所有表格,將表格逐一匯出為 txt 文字檔案
for table in tqdm(arcpy.ListTables()):
    arcpy.ExportTable_conversion(table, f"Pre_Jilin_Year_Table/{table}.txt")
print("轉換完成!")

2023 年的統計資訊文字如下所示:

image

2.5 將歷年的 txt 檔案整理為 Excel 表

import os
import pandas as pd

pre_dict = dict()
# 遍歷檔案列表
for fileName in os.listdir("Pre_Jilin_Year_Table"):
    # 透過字尾名判斷是否為 txt 檔案
    if fileName[-4:] == ".txt":
        # 基於 UTF-8 編碼讀取 txt 檔案內容
        with open(f"Pre_Jilin_Year_Table/{fileName}", "r", encoding="utf-8") as file:
            file_txt = file.readlines()
            # 文字內容的第一行是標題,第二行是資料
            # 讀取第二行資料第5個數值開始的所有資料值,即 MIN,MAX,RANGE,MEAN,STD,SUM,MEDIAN,PCT90
            # 注:ArcGIS Pro 不同版本轉換得到的 txt 資料表欄位可能不同,需要根據實際情況調整程式碼
            val_list = file_txt[1].replace("\n", "").split(",")[4:]
        # 將所有資料值從字串型別轉換為數值型別
        for i in range(len(val_list)):
            val_list[i] = eval(val_list[i])
        # 以數值型別年份為鍵,資料值列表為值,將資料存入字典
        pre_dict[eval(fileName[4:8])] = val_list

# 將字典轉換為 DataFrame 二維資料表
df = pd.DataFrame(pre_dict, index="MIN,MAX,RANGE,MEAN,STD,SUM,MEDIAN,PCT90".split(",")).T
print(df)

# 將 DataFrame 匯出為 Execl 表格
df.to_excel("Pre_Jilin_Year_Table.xlsx")
print("匯出表格完成!")

簡單調整 Excel 表的格式後,其展示效果如下圖所示:

image

2.6 基於歷年降水量生成多年平均降水量柵格

import os
import arcpy
from arcpy import sa

# 設定工作空間,並根據資料庫中的柵格資料數量確定年份數量
arcpy.env.workspace = "Pre_Jilin_Year.gdb"
year_num = len(arcpy.ListRasters())

# 定義變數名,並構建代數表示式,以對輸入柵格執行空間分析
# input_names = ["Pre_2001", "Pre_2002", "Pre_2003", ......, "Pre_2021", "Pre_2022", "Pre_2023"]
# expression = "(Pre_2001 + Pre_2002 + Pre_2003 + ...... + Pre_2021 + Pre_2022 + Pre_2023) / 23"
input_names, expression = [], ""
for raster in arcpy.ListRasters():
    input_names.append(raster)
    if expression == "":
        expression += raster
    else:
        expression += f" + {raster}"
expression = f"({expression}) / {year_num}"

# 如果在程式碼同級資料夾中沒有結果資料庫,則建立該資料庫
if "Pre_Jilin_Mean.gdb" not in os.listdir("."):
    print("即將為您建立用於儲存結果柵格的檔案地理資料庫(Pre_Jilin_Mean.gdb)……")
    arcpy.CreateFileGDB_management(".", "Pre_Jilin_Mean")
    print("資料庫建立完成!")

# 計算多年平均降水量柵格並儲存到結果資料庫中
sa.RasterCalculator(arcpy.ListRasters(), input_names, expression).save("Pre_Jilin_Mean.gdb/Pre_Mean")
print("計算完成!")

執行完成後生成的結果柵格如下圖所示:

image

3 降水資料參考文獻格式

3.1 資料的引用

彭守璋. (2020). 中國1km解析度逐月降水量資料集(1901-2023). 國家青藏高原資料中心. https://doi.org/10.5281/zenodo.3114194.

Peng, S. (2020). 1-km monthly precipitation dataset for China (1901-2023). National Tibetan Plateau / Third Pole Environment Data Center. https://doi.org/10.5281/zenodo.3114194.

3.2 文章的引用

1、Peng, S.Z., Ding, Y.X., Wen, Z.M., Chen, Y.M., Cao, Y., & Ren, J.Y. (2017). Spatiotemporal change and trend analysis of potential evapotranspiration over the Loess Plateau of China during 2011-2100. Agricultural and Forest Meteorology, 233, 183-194. https://doi.org/10.1016/j.agrformet.2016.11.129

2、Ding, Y.X., & Peng, S.Z. (2020). Spatiotemporal trends and attribution of drought across China from 1901–2100. Sustainability, 12(2), 477.

3、Peng, S.Z., Ding, Y.X., Liu, W.Z., & Li, Z. (2019). 1 km monthly temperature and precipitation dataset for China from 1901 to 2017. Earth System Science Data, 11, 1931–1946. https://doi.org/10.5194/essd-11-1931-2019

4、Peng, S., Gang, C., Cao, Y., & Chen, Y. (2017). Assessment of climate change trends over the loess plateau in china from 1901 to 2100. International Journal of Climatology.

相關文章