Как взять текущую или скользящую среднюю из нескольких ежедневных файлов - PullRequest
1 голос
/ 27 марта 2019

У меня есть 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

Ответы [ 2 ]

2 голосов
/ 27 марта 2019

Это не решение для 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), а затем выполните текущее среднее значение в python, здесь уже есть вопрос по стеку потока для этой задачи:

скользящее среднее или скользящее среднее

1 голос
/ 27 марта 2019

Что касается моего комментария выше:

"Сколько элементов у вас в каждом файле? ... Если бы каждый файл содержал тысячи точек сетки, я бы начал с сортировки различных точек сеткидля разделения файлов. Каждый файл будет содержать одну и ту же точку сетки для всех дат, отсортированных по дате. Таким образом, было бы просто загрузить весь файл одной точки сетки и рассчитать для него скользящее среднее. "

Теперь, когда у вас есть файл для одной точки сетки, я бы загрузил данные в список и выполнил этот простой расчет скользящего среднего.(Так как у вас есть доступ ко всему набору данных, вы можете использовать этот код. Для случаев, когда среднее значение вычисляется во время выполнения, а история результатов отсутствует, вы можете использовать указанные здесь алгоритмы: Википедия - Скользящее среднее * )

#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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...