我每天有11年(2007年至2017年)温度记录。共有11*365 = 4015
个NetCDF文件。每个文件均包含纬度(100,)
,经度(360,)
以及温度变量(360, 100)
。我想找到每个网格点的15天运行(移动)平均值,而忽略NaN
值(如果存在)。这意味着需要使用15个文件来查找均值。我具有以下功能,可以从文件夹中读取所有日常文件。例如需要找到files_list[0:15]
,files_list[1:16]
,files_list[2:17]....
,files_list[4000:]
的平均值。每个文件意味着需要另存为新的NetCDF文件。我有一个创建NetCDF文件的想法。但是找不到移动平均线。
这是我的代码:
def files_list (working_dir, extension):
'''
input = working directory and extension of file(eg. *.nc)
outout = returns the list of files in the folder
'''
file_full_path = os.path.join(working_dir)
os.chdir(working_dir)
files = glob.glob(os.path.join(file_full_path,extension))
files = natsort.natsorted(files)
files_list= [] #Empty lsit of files
j = 0
for j in range(0,len(files)):
files_list.append(os.path.basename(files[j])) #appending each files in a directory to file list
return files_list
答案 0 :(得分:2)
这不是python中的解决方案,但是如果您的文件名为file_20061105.nc等,则可以从命令行将其与cdo(气候数据运算符)合并,然后使用runmean函数
cdo mergetime file_*.nc merged_file.nc
cdo runmean,15 merged_file.nc runmean.nc
在某些系统上,可以打开的文件数量受到限制,在这种情况下,您可能需要每年一次合并文件
for year in {2007..2017} ; do
cdo mergetime file_${year}????.nc merged_${year}.nc
done
cdo mergetime merged_????.nc merged_file.nc
cdo runmean,15 merged_file.nc runmean.nc
这是从命令行快速完成此操作的另一种方法。
如果您想在python程序中执行此任务,则可以首先以这种方式将文件分类为一个文件(或循环使用python中的文件并将它们读入100x360x4000的单个numpy数组中),然后在python中执行运行平均值,这里已经有关于此任务的stackoverflow问题:
答案 1 :(得分:1)
关于我上面的评论:
“每个文件中有多少个项目?...如果每个文件包含数千个网格点,我会 首先将不同的网格点排序为单独的文件。每 文件将对所有日期保持相同的网格点,并按日期排序。这个 加载单个网格点的整个文件很简单 并计算出其运行平均值。”
现在您有了一个用于单个网格点的文件,我将把数据加载到列表中并运行此简单的移动平均值计算。 (由于您已访问整个数据集,因此可以使用此代码。对于在运行中计算平均值而没有结果历史记录的情况,可以使用此处指定的算法:Wikipedia - Moving Average)>
#Generate a list of 10 items
my_gridpoints_data=[x for x in range(1, 11)]
print(my_gridpoints_data)
#The average calculation window is set to 3, so the average is for 3 items at a time
avg_window_width: int = 3
avg: float = 0.0
sum: float = 0.0
# Calculate the average of the first 3 items (avg_window_width is 3)
for pos in range(0, avg_window_width):
sum = sum + my_gridpoints_data[pos]
avg = sum / avg_window_width
print(avg)
# Then move the window of the average by subtracting the leftmost item
# and adding a new item from the right
# Do this until the calculation window reaches the list's last item
for pos in range(avg_window_width, my_gridpoints_data.__len__()):
sum = sum + my_gridpoints_data[pos] - my_gridpoints_data[pos - avg_window_width]
avg = sum/avg_window_width
print(avg)
结果输出为:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
2.0
3.0
4.0
5.0
6.0
7.0
8.0
答案 2 :(得分:0)
回答得有点晚,但对于将来阅读的人,xarray
还提供了一种非常简单的Pythonic解决方案,与@Adrian Tomkins回答非常相似,该解决方案可以首先合并每年的文件,然后将它们合并在一起。一个文件,因为系统中可以打开的文件数有限。
for yr in range(2011,2018):
file_name = str(yr) + 'merge.nc'
xr.open_mfdataset(str(yr)*, combine='nested', concat_dim='time').to_netcdf(file_name)
xr.open_mfdataset(*merge.nc, combine='nested', concat_dim='time').to_netcdf(merge_all.nc)
ds = xr.open_dataset(merge_all.nc, chunks={'lat'=10, 'lon'=10}) # option to chunk if file size is too large, can also be used earlier with open_mfdataset
ds_rolling_mean = ds.rolling(time=15, center=True).mean()
编辑:xarray
相对于其他经典工具的一大优势在于,借助dask
,可以轻松进行内存不足的计算并在多个内核上扩展计算。例如,如果您必须在合并之前对文件进行一些预处理,则xr.open_mfdataset
将用户定义的预处理函数用作preprocess
参数,并设置'parallel = True'将对输入进行预处理合并前并行处理文件。