將NC柵格表示時間維度的資料提取出來的方法

疯狂学习GIS發表於2024-10-22

  本文介紹基於Python語言,逐一讀取大量.nc格式的多時相柵格檔案,匯出其中所具有的全部時間資訊的方法。

  .ncNetCDF(Network Common Data Form)檔案的副檔名,表示一種常用的科學資料儲存格式。NetCDF是一種自描述的、可移植的二進位制檔案格式,用於儲存科學和工程領域的大型資料集;由於其自身的特性,.nc資料被廣泛應用於氣象學、海洋學、地球科學、氣候研究、大氣科學、地理資訊系統等領域。

  首先,明確一下本文的需求。現在有一個資料夾,其中具有大量的.nc格式的柵格檔案,如下圖所示。

image

  其中,每一個.nc格式的檔案都具有多個時相(或者說是多個維度),而不僅僅只是一個時相。我們希望,讀取這個資料夾中的全部.nc格式檔案,並獲取其所表示的每一個時相。

  明確了需求後,我們就可以開始具體的操作。首先,本文所需用到的程式碼如下。

# -*- coding: utf-8 -*-
"""
Created on Sun Dec 31 20:28:03 2023

@author: fkxxgis
"""

import os
import netCDF4
from netCDF4 import Dataset

def list_nc_dates(folder_path):
    nc_dates = []

    for file_name in os.listdir(folder_path):
        if file_name.endswith(".nc"):
            file_path = os.path.join(folder_path, file_name)
            try:
                dataset = Dataset(file_path)
                time_var = dataset.variables["time"]
                time_values = time_var[:]
                time_units = time_var.units
                time_calendar = time_var.calendar

                dates = []
                for value in time_values:
                    date = netCDF4.num2date(value, units=time_units, calendar=time_calendar)
                    dates.append(date.strftime("%Y-%m-%d %H:%M:%S"))

                nc_dates.append((file_name, dates))
            except Exception as e:
                print(f"Error reading file {file_name}: {str(e)}")

    return nc_dates

folder_path = "F:/Data_Reflectance_Rec/soil_1"
nc_dates = list_nc_dates(folder_path)

for nc_file, dates in nc_dates:
    for date in dates:
        print(date)

  這段程式碼整體思路也很明確。

  首先,我們匯入所需的模組。在這裡,需要匯入Pythonos模組,用於處理檔案和資料夾路徑操作;同時匯入netCDF4庫,並接著從netCDF4庫中匯入Dataset類,用於開啟和讀取.nc檔案。在這裡,如果需要配置netCDF4庫,大家可以參考文章配置h5py、netCDF4庫的方法:Anaconda環境

  接下來,我們定義了一個名為list_nc_dates的函式,接受一個資料夾路徑作為引數。在函式中,首先建立一個空列表nc_dates,用於儲存每個.nc檔案及其對應的日期列表;隨後,使用os.listdir()函式遍歷資料夾中的所有檔案,透過檢查檔名是否以.nc結尾來篩選出.nc檔案。緊接著,對於篩選出來的.nc檔案,使用os.path.join()函式構建其完整路徑。

  其次,使用Dataset類開啟.nc檔案,並將開啟的檔案物件賦值給dataset變數;隨後,獲取.nc檔案的時間,在本文的.nc資料中,也就是名為time的變數,並將時間變數的值讀取到time_values變數中。接下來,分別獲取時間變數的單位與時間型別。

  隨後,我們建立一個空列表dates,用於儲存日期字串。遍歷時間變數的每個值,使用netCDF4.num2date()函式將時間值轉換為日期物件。緊接著,將日期物件轉換為指定格式的字串,並將其新增到dates列表中。此外,這裡還將.nc檔名和對應的日期列表作為元組新增到nc_dates列表中,方便我們後期對日期的核對。函式的最後,返回包含每個.nc檔案及其對應日期的列表。

  在函式外部,我們設定資料夾路徑,隨後即可呼叫list_nc_dates函式,將資料夾路徑傳遞給它,並將返回的結果賦值給nc_dates變數。最後,透過迴圈,列印每個日期即可。

  執行上述程式碼,即可出現如下圖所示的結果(結果很長,就擷取一部分)。由於在本文中,每一個.nc格式檔案的每一個維度(即每一個時相)都是精確到天的,所以下圖天數後的時、分、秒都是00。當然,如果大家的.nc格式檔案維度很多,時相列印出來的話也不好完全顯示,所以可以考慮將時間資訊匯出為表格檔案等;例如,可以將每一個date都放在DataFrame中,隨後匯出為.csv檔案。

  至此,大功告成。

相關文章