簡體   English   中英

循環通過netcdf文件並運行計算 - Python或R.

[英]Loop through netcdf files and run calculations - Python or R

這是我第一次使用netCDF,我正試着用它來解決這個問題。

我有多個版本3 netcdf文件(NOAA NARR air.2m每日平均一年)。 每個文件跨越1979年至2012年的一年。它們是349 x 277網格,分辨率約為32千米。 數據是從這里下載的。

維度是時間(自1800年1月1日以來的小時數),我感興趣的變量是空氣。 我需要計算溫度<0的累計天數。例如

    Day 1 = +4 degrees, accumulated days = 0
    Day 2 = -1 degrees, accumulated days = 1
    Day 3 = -2 degrees, accumulated days = 2
    Day 4 = -4 degrees, accumulated days = 3
    Day 5 = +2 degrees, accumulated days = 0
    Day 6 = -3 degrees, accumulated days = 1

我需要將這些數據存儲在一個新的netcdf文件中。 我熟悉Python並且熟悉R.什么是循環每天的最佳方法,檢查前一天的值,並在此基礎上,將值輸出到具有完全相同的維度和變量的新netcdf文件...或者可能只是使用我正在尋找的輸出將另一個變量添加到原始netcdf文件中。

最好將所有文件分開或組合起來嗎? 我將它們與ncrcat結合使用它工作正常,但文件是2.3gb。

感謝您的投入。

我目前在python中取得的進展:

import numpy
import netCDF4
#Change my working DIR
f = netCDF4.Dataset('air7912.nc', 'r')
for a in f.variables:
  print(a)

#output =
     lat
     long
     x
     y
     Lambert_Conformal
     time
     time_bnds
     air

f.variables['air'][1, 1, 1]
#Output
     298.37473

為了幫助我更好地理解我使用的數據結構類型是什么? ['air']是上例中的關鍵,[1,1,1]也是鍵嗎? 得到298.37473的價值。 我怎么能循環通過[1,1,1]?

您可以使用netCDF4中非常好的MFDataset功能將一堆文件視為一個聚合文件,而無需使用ncrcat 所以你的代碼看起來像這樣:

from pylab import *
import netCDF4

f = netCDF4.MFDataset('/usgs/data2/rsignell/models/ncep/narr/air.2m.19??.nc')
# print variables
f.variables.keys()

atemp = f.variables['air']
print atemp

ntimes, ny, nx = shape(atemp)
cold_days = zeros((ny,nx),dtype=int)

for i in xrange(ntimes):
    cold_days += atemp[i,:,:].data-273.15 < 0

pcolormesh(cold_days)
colorbar()

生成冷天的形象

這是編寫文件的一種方法(可能有更簡單的方法):

# create NetCDF file
nco = netCDF4.Dataset('/usgs/data2/notebook/cold_days.nc','w',clobber=True)
nco.createDimension('x',nx)
nco.createDimension('y',ny)

cold_days_v = nco.createVariable('cold_days', 'i4',  ( 'y', 'x'))
cold_days_v.units='days'
cold_days_v.long_name='total number of days below 0 degC'
cold_days_v.grid_mapping = 'Lambert_Conformal'

lono = nco.createVariable('lon','f4',('y','x'))
lato = nco.createVariable('lat','f4',('y','x'))
xo = nco.createVariable('x','f4',('x'))
yo = nco.createVariable('y','f4',('y'))
lco = nco.createVariable('Lambert_Conformal','i4')

# copy all the variable attributes from original file
for var in ['lon','lat','x','y','Lambert_Conformal']:
    for att in f.variables[var].ncattrs():
        setattr(nco.variables[var],att,getattr(f.variables[var],att))

# copy variable data for lon,lat,x and y
lono[:]=f.variables['lon'][:]
lato[:]=f.variables['lat'][:]
xo[:]=f.variables['x'][:]
yo[:]=f.variables['y'][:]

#  write the cold_days data
cold_days_v[:,:]=cold_days

# copy Global attributes from original file
for att in f.ncattrs():
    setattr(nco,att,getattr(f,att))

nco.Conventions='CF-1.6'
nco.close()

如果我嘗試在Unidata NetCDF-Java Tools-UI GUI中查看生成的文件,它似乎沒問題: 在此輸入圖像描述 另請注意,這里我剛下載了兩個用於測試的數據集,所以我使用了

f = netCDF4.MFDataset('/usgs/data2/rsignell/models/ncep/narr/air.2m.19??.nc')

舉個例子。 對於所有數據,您可以使用

f = netCDF4.MFDataset('/usgs/data2/rsignell/models/ncep/narr/air.2m.????.nc')

要么

f = netCDF4.MFDataset('/usgs/data2/rsignell/models/ncep/narr/air.2m.*.nc')

這是一個R解決方案。

infiles <- list.files("data", pattern = "nc", full.names = TRUE, include.dirs = TRUE)

outfile <- "data/air.colddays.nc"     

library(raster)

r <- raster::stack(infiles) 
r <- sum((r - 273.15) < 0)

plot(r)

在此輸入圖像描述

我知道從2013年開始這個帖子的時間已經相當晚了,但我只是想指出,所接受的解決方案並沒有為提出的確切問題提供解決方案。 這個問題似乎要求每個連續溫度低於零的時間長度(如果溫度超過零,則計數器重置的問題),這對氣候應用(例如農業)很重要,而接受的解決方案只給出總數溫度低於零的一年中的天數。 如果這真的是mkmitchell想要的(它已被接受為答案)那么它可以從cdo中的命令行完成,而不必擔心NETCDF輸入/輸出:

 cdo timsum -lec,273.15 in.nc out.nc

所以一個循環的腳本將是:

files=`ls *.nc` # pick up all the netcdf files in a directory
for file in $files ; do
    # I use 273.15 as from the question seems T is in Kelvin 
    cdo timsum -lec,273.15 $file ${file%???}_numdays.nc
done 

如果您想要整個期間的總數,那么您可以使用_numdays文件而不是更小:

cdo cat *_numdays.nc total.nc 
cdo timsum total.nc total_below_zero.nc 

但同樣,這個問題似乎需要每個事件累積的天 ,這是不同的,但不是由接受的答案提供。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM