Обработка климатических данных с rp5

В процессе работы с  климатическими данными WorldClim возникли сомнения относительно их валидности в отношении одной из позиций на территории Приморского края. Оказалось, что среднегодовая температура одной из точек Хасанского района, согласно WorldClim,  1.7 градусов (по Цельсию). Это подозрительно низкое значение, тем более, для юга Приморского края (должна быть, по крайней мере, около 4 градусов). В связи с этим возникла задача получить "похожие" (а именно, задача формулировалась как отыскание средней, минимальной и максимальной температуры и влажности для определенного месяца) климатические показатели из другого источника. В качестве такого альтернативного источника был выбран сервис rp5.ru, предоставляющий архивы климатических измерений (частотой ~8 измерений в сутки) за последние 10 лет для нескольких населенных пунктов Приморского края.

Задача обработки исходных архивных данных погоды состояла в получении средних месячных показателей температуры, относительной влажности, количества осадков. Размер исходной таблицы — 29 столбцов и не менее 29 тыс. строк (если интервал формирования архива составляет 10 лет). Каждая строка соответствует определенному времени измерения.

На каждый месяц приходится в среднем около 240 записей. Необходимо было формировать выборки из общей таблицы данных, соответствующие определенному месяцу и году и рассчитывать для них среднее, минимальное и максимальное значения температуры, влажности, количества осадков.

Выполнить такую работу в Excel оказалось весьма трудоемко в плане выполнения однообразной работы, поэтому было решено реализовать простой скрипт на Python с использованием пакета pandas.

Для начала были загружены данные погоды для владивостока за временной интервал 01.01.2005 по 02.10.2015 г.  Данные были загружены как xsl-документ и впоследствии средствами OpenOffice сохранены в csv-формате со следующей "шапкой":

time	T	Po	P	Pa	U	DD	Ff	ff10	ff3	N	WW	W1	W2	Tn	Tx	Cl	Nh	H	Cm	Ch	VV	Td	RRR	tR	E	Tg	E'	sss

Сервис rp5 позволяет "сразу" сохранять климатические данные в нужно формате csv. Тем не менее, мой опыт показал, что ручная конвертация из xls в csv здесь более предпочтительна, т.к. в этом случае пакет pandas позволяет считать данные "без проблем"; в то время как экспортирование данных непосредственно в csv приводило к ошибкам в процессе их загрузки при помощи pandas (это, однако, было раньше, и возможно сейчас ситуация изменилась, не проверял).

Полученный файл csv легко может быть загружен при помощи pandas.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import pandas as pd
from datetime import datetime as dt
import numpy as np
from string import join


def tryfloat(x):
    '''Safely converts string to float.'''
    try:
        res = float(x)
    except ValueError:
        return np.nan
    return res


def getpars(x):
    '''Get necessary paramters.'''
    try:
        res = [str(x.mean(skipna=True)), str(x.max(skipna=True)), str(x.min(skipna=True))]
    except:
        res = ['', '', '']
    return res


#Input filename
FILENAME = 'vlad.csv'

#Read the data to memory
data = pd.read_csv(FILENAME)

#IMPORTANT!!! One need to specify format for datetime conversion
#Current format provided by rp5 is day.month.year hour:minute
data['time'] = pd.to_datetime(data['time'], format='%d.%m.%Y %H:%M')

#Convert loaded parameters of interest to floats
data['T'] = data['T'].map(lambda x: tryfloat(str(x).strip().replace(',','.'))) #temperature     
data['U'] = data['U'].map(lambda x: tryfloat(str(x).strip().replace(',','.'))) #humidity
data['RRR'] = data['RRR'].map(lambda x: tryfloat(str(x).strip().replace(',','.'))) #precipitation

#open the output file
f = open('output.csv','w')

#mean by month and year
month = 5 # Lets be May?!

#iterate over all `available months`
for year in range(2005, 2016):
    crit = data['time'].map(lambda x: x.year==year and x.month==month)
    curdata = data.copy()[crit]
    row = str(year) + ',' + join(getpars(curdata['T']), sep=',') + ',' + \
join(getpars(curdata['U']), sep=',') + ',' + join(getpars(curdata['RRR']), sep=',')
    f.write(row+'\n')
    
#close the file with outputs
f.close()

Отметим очень важный момент. Без указания формата для преобразования дат, программа также будет работать "без ошибок", но произойдет путаница в соответствии климатических данных реальным месяцам. Не учитывая этого, полагая, что функция распознавания дат в pandas "достаточно умна",  у меня получались результаты минимальных температур в мае до –20 градусов (для Владивостока). Это нехарактерно низкая температура для этого месяца. После указания правильного формата (см. вышеприведенный код), результаты стали получаться более правдоподобными — от 0 до 4 градусов по Цельсию  для минимальных температур мая во Владивостоке.

Пример динамики температур во Владивостоке 2005-2015 гг

Для отрисовки графика температур дополнительно был использован следующий код:

from pylab import *
rc('font', **{'family': 'monospace', 'weight': 'bold', 'size': 30})
plot_date(data['time'][::50],data['T'][::50],'-')
show()

Результаты работы скрипта представленны следующими таблицами:

Пример csv-файла климатических данных по Владивостоку (2005-2015) (14,3 MB)

Результат работы скрипта (параметры температуры, влажности и количества осадков) (818 bytes)


 

blog comments powered by Disqus