Как рассчитать среднемесячное годовое среднее значение из дневного фрейма данных и построить его по сокращенному месяцу - PullRequest
0 голосов
/ 11 июля 2020

У меня есть суточные значения осадков и температуры за период в несколько лет. Я хотел бы вычислить среднее количество осадков и температуры для каждого месяца в году (с января по декабрь). Для осадков мне сначала нужно рассчитать сумму суточных осадков за каждый месяц, а затем вычислить среднее значение за тот же месяц для всех данных за все годы. Для температуры мне нужно усреднить среднемесячные значения (поэтому среднее значение всех данных за все месяцы дает точно такой же результат). Как только это будет сделано, мне нужно построить оба набора данных (осадки и температура), используя сокращенные месяцы.

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

Это то, что я пробовал до сих пор (безуспешно):

import pandas as pd

import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter

example = [['01.10.1965 00:00', 13.88099957,    5.375],
    ['02.10.1965 00:00',    5.802999973,    3.154999971],
    ['03.10.1965 00:00',    9.605699539,    0.564999998],
    ['14.10.1965 00:00',    0.410299987,    1.11500001],
    ['31.10.1965 00:00',    6.184500217,    -0.935000002],
    ['01.11.1965 00:00',    0.347299993,    -5.235000134],
    ['02.11.1965 00:00',    0.158299997,    -8.244999886],
    ['03.11.1965 00:00',    1.626199961,    -3.980000019],
    ['24.10.1966 00:00',    0,              3.88499999],
    ['25.10.1966 00:00',    0.055100001,    1.279999971],
    ['30.10.1966 00:00',    0.25940001,     -5.554999828]]

names = ["date","Pobs","Tobs"]
data = pd.DataFrame(example, columns=names)
data['date'] = pd.to_datetime(data['date'], format='%d.%m.%Y %H:%M')

#I think the average of temperature is well computed but the precipitation would give the complete summation for all years!
tempT = data.groupby([data['date'].dt.month_name()], sort=False).mean().eval('Tobs')
tempP = data.groupby([data['date'].dt.month_name()], sort=False).sum().eval('Pobs') 

fig = plt.figure(); ax1 = fig.add_subplot(1,1,1); ax2 = ax1.twinx();
ax1.bar(tempP.index.tolist(), tempP.values, color='blue')
ax2.plot(tempT.index.tolist(), tempT.values, color='red')
ax1.set_ylabel('Precipitation [mm]', fontsize=10)
ax2.set_ylabel('Temperature [°C]', fontsize=10) 
#ax1.xaxis.set_major_formatter(DateFormatter("%b")) #this line does not work properly!
plt.show()

1 Ответ

0 голосов
/ 11 июля 2020

Вот рабочий код для вашей проблемы:

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter
import matplotlib.dates as mdates

example = [['01.10.1965 00:00',13.88099957,5.375], ...]

names = ["date","Pobs","Tobs"]
data = pd.DataFrame(example, columns=names)
data['date'] = pd.to_datetime(data['date'], format='%d.%m.%Y %H:%M')

# Temperature:
tempT = data.groupby([data['date'].dt.month_name()], sort=False).mean().eval('Tobs')

# Precipitation:
df_sum = data.groupby([data['date'].dt.month_name(), data['date'].dt.year], sort=False).sum()  # get sum for each individual month
df_sum.index.rename(['month','year'], inplace=True)  # just renaming the index
df_sum.reset_index(level=0, inplace=True)  # make the month-index to a column
tempP = df_sum.groupby([df_sum['month']], sort=False).mean().eval('Pobs')  # get mean over all years

fig = plt.figure();
ax1 = fig.add_subplot(1,1,1);
ax2 = ax1.twinx();

xticks = pd.to_datetime(tempP.index.tolist(), format='%B').sort_values() # must work for both axes
ax1.bar(xticks, tempP.values, color='blue')
ax2.plot(xticks, tempT.values, color='red')
plt.xticks(pd.to_datetime(tempP.index.tolist(), format='%B').sort_values()) # to show all ticks

ax1.xaxis.set_major_formatter(mdates.DateFormatter("%b")) # must be called after plotting both axes

ax1.set_ylabel('Precipitation [mm]', fontsize=10)
ax2.set_ylabel('Temperature [°C]', fontsize=10)

plt.show()

Объяснение: В этом ответе StackOverflow DateFormatter использует mdates. Чтобы это сработало, вам нужно создать DatetimeIndex-Array из названий месяцев, которые DateFormatter может затем переформатировать.

Что касается расчета, я понял решение вашей проблемы как таковое, что мы берем сумму в каждом за месяц, а затем возьмите среднее значение этих сумм за все годы . Это оставляет вам среднее количество осадков в месяц за все годы.

...