处理闰年2月29号的两种方法

关于处理闰年2月29号数据的两种方法。

这里以一个2008年的SLP数据为例(2008年为闰年,有2月29号,共366天)。

首先读取数据:

1
2
3
4
import xarray as xr
#############读入数据########
f_in = xr.open_dataset('./slp.2008.nc')
print(f_in,'\n')

输出结果是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<xarray.Dataset>
Dimensions: (lat: 73, lon: 144, time: 366)
Coordinates:
* lat (lat) float32 90.0 87.5 85.0 82.5 80.0 ... -82.5 -85.0 -87.5 -90.0
* lon (lon) float32 0.0 2.5 5.0 7.5 10.0 ... 350.0 352.5 355.0 357.5
* time (time) datetime64[ns] 2008-01-01 2008-01-02 ... 2008-12-31
Data variables:
slp (time, lat, lon) float32 ...
Attributes:
Conventions: COARDS
title: mean daily NMC reanalysis (2008)
description: Data is from NMC initialized reanalysis\n(4x/day). It co...
platform: Model
history: created 2007/12 by Hoop (netCDF2.3)\nConverted to chunked...
dataset_title: NCEP-NCAR Reanalysis 1
References: http://www.psl.noaa.gov/data/gridded/data.ncep.reanalysis...

我们想删去其中的2月29日,这里提供两种方法。

第一种暴力一点,直接利用CDO把数据文件中的2.29这一天删去(一旦删去不可恢复,注意备份文件)。

1
2
3
!cdo delete,month=2,day=29 './slp.2008.nc' './out1.nc'
f_out1 = xr.open_dataset('./out1.nc')
print(f_out1,'\n')

这三行代码可以直接在jupyter notebook的脚本中运行,!为调用外部指令的意思,也可使用os.system()方法调用。还可以去掉“!”符号,直接用cdo指令在shell中使用。输出结果为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<xarray.Dataset>
Dimensions: (lat: 73, lon: 144, time: 365)
Coordinates:
* time (time) datetime64[ns] 2008-01-01 2008-01-02 ... 2008-12-31
* lon (lon) float32 0.0 2.5 5.0 7.5 10.0 ... 350.0 352.5 355.0 357.5
* lat (lat) float32 90.0 87.5 85.0 82.5 80.0 ... -82.5 -85.0 -87.5 -90.0
Data variables:
slp (time, lat, lon) float32 ...
Attributes:
CDI: Climate Data Interface version 2.1.1 (https://mpimet.mpg....
Conventions: COARDS
title: mean daily NMC reanalysis (2008)
description: Data is from NMC initialized reanalysis\n(4x/day). It co...
platform: Model
history: Wed Mar 15 16:03:16 2023: cdo delete,month=2,day=29 ./slp...
dataset_title: NCEP-NCAR Reanalysis 1
References: http://www.psl.noaa.gov/data/gridded/data.ncep.reanalysis...
CDO: Climate Data Operators version 2.1.1 (https://mpimet.mpg....

第二种则是利用xarray的索引来避免选择2月29这一天,对原文件不进行操作:

1
2
slp = f_in.slp.loc[~((f_in.time.dt.month==2)&(f_in.time.dt.day==29))]
print(slp)

~在python中为取反的含义,因此索引中的内容实际为,选择月为2且日为29的反集。输出结果为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<xarray.DataArray 'slp' (time: 365, lat: 73, lon: 144)>
[3836880 values with dtype=float32]
Coordinates:
* lat (lat) float32 90.0 87.5 85.0 82.5 80.0 ... -82.5 -85.0 -87.5 -90.0
* lon (lon) float32 0.0 2.5 5.0 7.5 10.0 ... 350.0 352.5 355.0 357.5
* time (time) datetime64[ns] 2008-01-01 2008-01-02 ... 2008-12-31
Attributes:
long_name: mean Daily Sea Level Pressure
units: Pascals
precision: 0
GRIB_id: 2
GRIB_name: PRMSL
var_desc: Sea Level Pressure
dataset: NCEP Reanalysis Daily Averages
level_desc: Sea Level
statistic: Mean
parent_stat: Individual Obs
actual_range: [ 93755. 109700.]
valid_range: [ 87000. 115000.]