我正在尝试从几个 NetCDF 文件中制作一些地图等数据。每一项都包含 5 年的数据。数据位于形状为
(14608, 145, 192)
(时间、纬度、经度)的 3D 数组中。
我想要每个坐标每年的最大值,所以基本上当一切都说完并完成后,我将得到一个形状为
(5,145,192)
的输出数组(每个纬度和经度值一个值)。
有人建议我尝试使用 pandas,特别是 DataFrame 和 DatetimeIndex,但我找不到一种方法来将它用于比 2D 数组更大的东西。还建议使用 Xarray,但我以前没有使用过 xarray,不知道从哪里开始。
编辑 1:示例数据
这是我一直尝试用 pandas 做的简化版本,然后我意识到 DataFrame 不适用于 3D 数组。
import numpy as np
import pandas as pd
fake = np.random.randint(2, 30, size = (14608,145,192))
index = pd.date_range(start = '1985-1-1 01:30:00', end = '1989-12-31 22:30:00' , freq='3H')
df = pd.DataFrame(data = fake, index = index)
编辑 2:固定列出的数组形状
为了澄清,我实际上想要一个形状为
(5, 145, 192)
的数组作为输出。我写错了,因为最初我将 3D 数组分成 5 个单独的数组,找到最大值,然后将它们再次堆叠到一个以 (5, 145, 192)
形状结尾的数组中。
我希望能够跳过我之前所做的手动分解数组的繁琐工作并简化代码。
以下是使用 Xarray 解决此问题的方法:
import xarray as xr
# open one of your files
ds = xr.open_dataset('path/to/your/ncfile.nc')
# find maximum for a specific year (1990 in this example)
ds_ymax = ds.sel(time=slice('1990-01-01', '1990-12-31')).max('time')
# plot a single variable ('temperature' in this example)
ds_ymax['temperature'].plot()
虽然这涵盖了您想要做的事情的基础知识,但我认为我应该提到一些其他常见的工作流程:
一次打开多个文件。 Xarray 提供了
open_mfdataset
功能,允许一次快速串联多个文件:
ds = xr.open_mfdataset('path/to/your/ncfiles/*nc') # note the use of the wildcard
使用resample计算年度最大值。在上面的示例中,我手动选择了一年的数据,但可以使用 resample 或 groupby 以编程方式执行此操作
# using resample ('AS' == annual starting Jan-1)
ds_ymax = ds.resample(time='AS').max('time')
# using groupby
ds_ymax = ds.groupby('time.year').max('time')
最后,您提到不知道从哪里开始使用 xarray。查看文档:http://xarray.pydata.org/en/latest/index.html
如果您想要年度最大值(即每年每个网格点一个值),那么您可以使用
cdo
: 从命令行执行此操作
cdo yearmax in.nc out.nc
您可以通过使用 cdo 包在 python 中使用这些函数,安装时:
pip install cdo
所以Python代码是
from cdo import Cdo
cdo=Cdo()
cdo.yearmax(input="in.nc",output="out.nc")
更多详细信息请参见:https://code.mpimet.mpg.de/projects/cdo/embedded/index.html
您可以在这里使用
Panel
df = pd.Panel(fake).to_frame()
df.columns=index
df
Out[1065]:
1985-01-01 01:30:00 1985-01-01 04:30:00 1985-01-01 07:30:00
major minor
0 0 28 7 22
1 9 10 11
2 8 15 7
3 19 18 2
4 14 16 24
5 6 26 13
6 28 16 11
#....