xarray 计算多年 netcdf 的月平均值
xarray computing monthly mean from multiple year netcdf
我有一个来自 ERA5 的 2m 温度 netcdf 文件,从 2000 年到 2019 年的 04 到 10 个月,总共有 13680 个时间步长和 61x161 lat-lon 维度。我想分别对每年的所有每日时间步长进行每月平均。例如,我们将获得 2000 年 4 月、2000 年 5 月等数据的月平均值。我用 xarray resample 尝试了以下代码,但出现了两个问题。
- 出于某种原因,平均值似乎一直都是平均值。
- resample 函数创建了月份 01、02、03、11 和 12,尽管没有数据!
我要说的是:
import xarray as xr
ds = xr.open_dataset(netcdf)
monthly_data=ds.resample(time='1M').mean()
我们可以看看时间戳,它显示了每月的时间步长,包括不相关的月份。
print(np.array(monthly_data.time))
array(['2000-04-30T00:00:00.000000000', '2000-05-31T00:00:00.000000000',
'2000-06-30T00:00:00.000000000', '2000-07-31T00:00:00.000000000',
'2000-08-31T00:00:00.000000000', '2000-09-30T00:00:00.000000000',
'2000-10-31T00:00:00.000000000', '2000-11-30T00:00:00.000000000',
'2000-12-31T00:00:00.000000000', '2001-01-31T00:00:00.000000000',
为了验证温度的内容,我把数据变成了dataframe。
temp_ar = np.array(monthly_data.t2m)
print(pd.DataFrame(temp_ar[0,:,:]).head())
0 1 2 ... 158 159 160
0 270.940613 270.911652 270.926727 ... NaN NaN NaN
1 271.294952 271.256744 271.250946 ... 272.948608 272.974731 272.998535
2 271.416779 271.457214 271.483459 ... 273.123169 273.079285 273.058563
3 271.848755 271.791382 271.784058 ... NaN 273.264038 NaN
4 272.226837 272.144928 272.123016 ... NaN NaN NaN
print(pd.DataFrame(temp_ar[1,:,:]).head())
0 1 2 3 4 5 6 ... 154 155 156 157 158 159 160
0 NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN
1 NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN
2 NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN
3 NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN
4 NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN
第二个数组(对应于 2000 年 05 月)不应该有 nans,但它确实有 nans,并且对于所有其他时间步长都是这样(由于某种原因,最后一个除外)。有人知道为什么会这样吗?
这是原始数据集
print(ds)
<xarray.Dataset>
Dimensions: (latitude: 61, longitude: 161, time: 13680)
Coordinates:
* longitude (longitude) float32 -80.0 -79.9 -79.8 -79.7 ... -64.2 -64.1 -64.0
* latitude (latitude) float32 50.0 49.9 49.8 49.7 ... 44.3 44.2 44.1 44.0
* time (time) datetime64[ns] 2000-04-01 ... 2018-10-30T23:00:00
Data variables:
t2m (time, latitude, longitude) float32 ...
Attributes:
Conventions: CF-1.6
history: 2020-12-07 03:50:31 GMT by grib_to_netcdf-2.16.0: /opt/ecmw...
任何帮助都是。也许我应该尝试其他方法?
干杯!
我认为任何简单的方法都是使用 groupby
method
示例:
da = xr.DataArray(
np.linspace(0, 1673, num=1674),
coords=[pd.date_range("1/1/2000", "31/07/2004", freq="D")],
dims="time",
)
da
输出:
<xarray.DataArray (time: 1674)>
array([0.000e+00, 1.000e+00, 2.000e+00, ..., 1.671e+03, 1.672e+03, 1.673e+03])
Coordinates:
* time (time) datetime64[ns] 2000-01-01 2000-01-02 ... 2004-07-31
对于每年平均你可以做的:
da.groupby('time.year').mean()
输出:
<xarray.DataArray (year: 5)>
array([ 182.5, 548. , 913. , 1278. , 1567. ])
Coordinates:
* year (year) int64 2000 2001 2002 2003 2004
对于不同年份的每个月的平均值,您可以创建一个多索引:
year_month_idx = pd.MultiIndex.from_arrays([da['time.year'], da['time.month']])
da.coords['year_month'] = ('time', year_month_idx)
da.groupby('year_month').mean()
输出:
<xarray.DataArray (year_month: 55)>
array([ 15. , 45. , 75. , 105.5, 136. , 166.5, 197. , 228. , 258.5,
289. , 319.5, 350. , 381. , 410.5, 440. , 470.5, 501. , 531.5,
562. , 593. , 623.5, 654. , 684.5, 715. , 746. , 775.5, 805. ,
835.5, 866. , 896.5, 927. , 958. , 988.5, 1019. , 1049.5, 1080. ,
1111. , 1140.5, 1170. , 1200.5, 1231. , 1261.5, 1292. , 1323. , 1353.5,
1384. , 1414.5, 1445. , 1476. , 1506. , 1536. , 1566.5, 1597. , 1627.5,
1658. ])
Coordinates:
* year_month (year_month) MultiIndex
* year_month_level_0 (year_month) int64 2000 2000 2000 ... 2002 2002 2002
* year_month_level_1 (year_month) int64 1 2 3 4 5 6 7 8 ... 11 12 1 2 3 4 5 6
我有一个来自 ERA5 的 2m 温度 netcdf 文件,从 2000 年到 2019 年的 04 到 10 个月,总共有 13680 个时间步长和 61x161 lat-lon 维度。我想分别对每年的所有每日时间步长进行每月平均。例如,我们将获得 2000 年 4 月、2000 年 5 月等数据的月平均值。我用 xarray resample 尝试了以下代码,但出现了两个问题。
- 出于某种原因,平均值似乎一直都是平均值。
- resample 函数创建了月份 01、02、03、11 和 12,尽管没有数据!
我要说的是:
import xarray as xr
ds = xr.open_dataset(netcdf)
monthly_data=ds.resample(time='1M').mean()
我们可以看看时间戳,它显示了每月的时间步长,包括不相关的月份。
print(np.array(monthly_data.time))
array(['2000-04-30T00:00:00.000000000', '2000-05-31T00:00:00.000000000',
'2000-06-30T00:00:00.000000000', '2000-07-31T00:00:00.000000000',
'2000-08-31T00:00:00.000000000', '2000-09-30T00:00:00.000000000',
'2000-10-31T00:00:00.000000000', '2000-11-30T00:00:00.000000000',
'2000-12-31T00:00:00.000000000', '2001-01-31T00:00:00.000000000',
为了验证温度的内容,我把数据变成了dataframe。
temp_ar = np.array(monthly_data.t2m)
print(pd.DataFrame(temp_ar[0,:,:]).head())
0 1 2 ... 158 159 160
0 270.940613 270.911652 270.926727 ... NaN NaN NaN
1 271.294952 271.256744 271.250946 ... 272.948608 272.974731 272.998535
2 271.416779 271.457214 271.483459 ... 273.123169 273.079285 273.058563
3 271.848755 271.791382 271.784058 ... NaN 273.264038 NaN
4 272.226837 272.144928 272.123016 ... NaN NaN NaN
print(pd.DataFrame(temp_ar[1,:,:]).head())
0 1 2 3 4 5 6 ... 154 155 156 157 158 159 160
0 NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN
1 NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN
2 NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN
3 NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN
4 NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN
第二个数组(对应于 2000 年 05 月)不应该有 nans,但它确实有 nans,并且对于所有其他时间步长都是这样(由于某种原因,最后一个除外)。有人知道为什么会这样吗?
这是原始数据集
print(ds)
<xarray.Dataset>
Dimensions: (latitude: 61, longitude: 161, time: 13680)
Coordinates:
* longitude (longitude) float32 -80.0 -79.9 -79.8 -79.7 ... -64.2 -64.1 -64.0
* latitude (latitude) float32 50.0 49.9 49.8 49.7 ... 44.3 44.2 44.1 44.0
* time (time) datetime64[ns] 2000-04-01 ... 2018-10-30T23:00:00
Data variables:
t2m (time, latitude, longitude) float32 ...
Attributes:
Conventions: CF-1.6
history: 2020-12-07 03:50:31 GMT by grib_to_netcdf-2.16.0: /opt/ecmw...
任何帮助都是。也许我应该尝试其他方法? 干杯!
我认为任何简单的方法都是使用 groupby
method
示例:
da = xr.DataArray(
np.linspace(0, 1673, num=1674),
coords=[pd.date_range("1/1/2000", "31/07/2004", freq="D")],
dims="time",
)
da
输出:
<xarray.DataArray (time: 1674)>
array([0.000e+00, 1.000e+00, 2.000e+00, ..., 1.671e+03, 1.672e+03, 1.673e+03])
Coordinates:
* time (time) datetime64[ns] 2000-01-01 2000-01-02 ... 2004-07-31
对于每年平均你可以做的:
da.groupby('time.year').mean()
输出:
<xarray.DataArray (year: 5)>
array([ 182.5, 548. , 913. , 1278. , 1567. ])
Coordinates:
* year (year) int64 2000 2001 2002 2003 2004
对于不同年份的每个月的平均值,您可以创建一个多索引:
year_month_idx = pd.MultiIndex.from_arrays([da['time.year'], da['time.month']])
da.coords['year_month'] = ('time', year_month_idx)
da.groupby('year_month').mean()
输出:
<xarray.DataArray (year_month: 55)>
array([ 15. , 45. , 75. , 105.5, 136. , 166.5, 197. , 228. , 258.5,
289. , 319.5, 350. , 381. , 410.5, 440. , 470.5, 501. , 531.5,
562. , 593. , 623.5, 654. , 684.5, 715. , 746. , 775.5, 805. ,
835.5, 866. , 896.5, 927. , 958. , 988.5, 1019. , 1049.5, 1080. ,
1111. , 1140.5, 1170. , 1200.5, 1231. , 1261.5, 1292. , 1323. , 1353.5,
1384. , 1414.5, 1445. , 1476. , 1506. , 1536. , 1566.5, 1597. , 1627.5,
1658. ])
Coordinates:
* year_month (year_month) MultiIndex
* year_month_level_0 (year_month) int64 2000 2000 2000 ... 2002 2002 2002
* year_month_level_1 (year_month) int64 1 2 3 4 5 6 7 8 ... 11 12 1 2 3 4 5 6