【问题标题】:How to take the running or moving average from multiple daily files如何从多个每日文件中获取运行平均值或移动平均值
【发布时间】:2019-03-27 05:29:42
【问题描述】:

我有 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

【问题讨论】:

  • 每个文件有多少项?请分享这样一个文件的sn-p。如果每个文件包含数千个网格点,我将从将不同的网格点排序到单独的文件开始。每个文件将为所有日期保存相同的网格点,按日期排序。这样,加载单个网格点的整个文件并计算其运行平均值会很简单。

标签: python netcdf python-xarray


【解决方案1】:

这不是 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问题:

Moving average or running mean

【讨论】:

  • 这是否适用于太大而无法放入 RAM 的数据,例如,当 merged_file.nc 为 100s GB 时?
【解决方案2】:

关于我上面的评论:

“每个文件有多少项?...如果每个文件包含数千个网格点,我会 首先将不同的网格点排序到单独的文件中。每个 文件将为所有日期保存相同的网格点,按日期排序。这 加载单个网格点的整个文件的方式很简单 并计算它的运行平均值。”

现在您已经有了单个网格点的文件,我会将数据加载到列表中并运行这个简单的运行平均值计算。 (由于您可以访问整个数据集,因此可以使用此代码。对于在运行中计算平均值且没有结果历史记录的情况,您可以使用此处指定的算法: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

【讨论】:

  • 为什么要分成网格点?那将是一种极其缓慢的方法。如果您在任何地方都执行相同的操作,那么您没有理由可以跨整个域进行操作。
  • @AdrianTompkins,我建议在执行计算之前分离网格点,因为我不知道数据集的大小。我们知道它由大约 4000 个文件组成,但也许每个文件都包含一百万个点的数据。在计算之前安排数据允许更简单的平均计算算法。
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 2013-12-24
    • 1970-01-01
    • 1970-01-01
    • 2020-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-12
    相关资源
    最近更新 更多