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

问题描述 投票:1回答:2

我有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
python netcdf python-xarray
2个回答
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问题:

Moving average or running mean


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
© www.soinside.com 2019 - 2024. All rights reserved.