为了账号安全,请及时绑定邮箱和手机立即绑定

如何从多个每日文件中获取运行或移动平均值

如何从多个每日文件中获取运行或移动平均值

慕慕森 2021-12-17 15:47:18
我有 11 年(2007 年到 2017 年)的每日温度文件。总共有11*365 = 4015NetCDF 文件。每个文件都包含纬度(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
查看完整描述

3 回答

?
素胚勾勒不出你

TA贡献1827条经验 获得超9个赞

这不是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程序中完成这个任务,那么你可以先用这种方式将文件cat成一个(或在python中循环文件并将它们读入一个100x360x4000的numpy数组),然后执行运行意思是在python中


查看完整回答
反对 回复 2021-12-17
?
饮歌长啸

TA贡献1951条经验 获得超3个赞

至于我上面的评论:


“每个文件中有多少项目?...如果每个文件包含数千个网格点,我会首先将不同的网格点排序为单独的文件。每个文件将保存所有日期的相同网格点,按以下顺序排序日期。这样就可以轻松加载单个网格点的整个文件并计算其运行平均值。”


现在您有一个用于单个网格点的文件,我会将数据加载到列表中并运行这个简单的运行平均值计算。(由于您可以访问整个数据集,您可以使用此代码。对于在运行时计算平均值并且没有结果历史记录的情况,您可以使用此处指定的算法:维基百科 - 移动平均)


#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


查看完整回答
反对 回复 2021-12-17
?
回首忆惘然

TA贡献1847条经验 获得超11个赞

回答有点晚,但对于将来阅读的人来说,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' 将在合并之前并行预处理您的输入文件。


查看完整回答
反对 回复 2021-12-17
  • 3 回答
  • 0 关注
  • 299 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信