【问题标题】:How to calculate monthly mean of a time seies data and substract the monthly mean with the values of that month of each year?如何计算时间序列数据的月均值,并用每年该月的值减去月均值?
【发布时间】:2020-02-07 14:51:52
【问题描述】:

数据集是一个由 9 个变量组成的每日时间序列
我已经提取了数据集

Data = pd.read_csv('city10.csv', header = None)
Data['Date'] = pd.date_range(start='1/1/1951', periods=len(Data), freq='D')
Data.set_index('Date', inplace=True)

看起来像这样

 Date         0    1       2       3  ...       5       6         7        8                                  
1951-01-01  28.361  0.0  131.24  405.39  ...  405.39  38.284  0.187010 -1.23550  
1951-01-02  27.874  0.0  113.74  409.56  ...  409.56  49.834  0.066903 -1.44770  
           ...  ...     ...     ...  ...     ...     ...       ...      ...  
2005-12-16  27.921  0.0  104.99  429.78  ...  429.78  47.529 -1.814300 -5.47720  
2005-12-17  27.918  0.0  112.11  425.32  ...  425.32  46.541 -3.314000 -4.02050 

在此之后,我找到了整个数据集的月份平均值,即

Data.groupby(Data.index.month).mean()

结果是

              0         1           2  ...          6         7         8                              
1     29.619322  0.215978  108.621532  ...  45.868395 -0.234236 -1.865947
2     32.404500  0.290335   95.270385  ...  43.443624  0.554149 -2.360776
3     35.131266  0.364438   78.907920  ...  42.065113  1.458203 -2.636451
4     36.631282  0.998401   53.663939  ...  44.239469  3.146849 -2.193416
5     36.823308  2.113330   37.917831  ...  54.287356  5.241153 -0.694375
6     34.444513  2.195926   35.315554  ...  67.840239  6.393643  0.689087
7     32.951826  3.567160   32.466668  ...  82.347247  6.583195  1.183262
8     32.644236  4.053641   36.379228  ...  85.056697  5.102383  0.005426
9     32.205442  4.885259   50.595568  ...  80.335829  2.413891 -0.578568
10    30.448266  5.748111   79.575731  ...  67.582589 -0.769297 -0.614057
11    28.748315  4.350384  100.293532  ...  53.418955 -1.258580 -1.023143
12    28.155611  1.524177  109.510292  ...  51.317731 -0.936495 -1.549105

现在,如何用每年那个月的相应值减去每个月的平均值。
例如 1951-2005 年时间序列的 1 月平均值为 20.25
这个平均值必须从所有一月份的每日值中减去。 如何做到这一点?

【问题讨论】:

  • 能否请您添加一些您尝试过的代码?
  • 请注意,如果您制作一个简短的示例并包含生成此示例的代码,您更有可能获得快速答案,请参阅我的答案开头的示例。
  • values = pd.read_csv('city10.csv', header = None) values['Date'] = pd.date_range(start='1/1/1951', period=len(values ), freq='D') values.set_index('Date', inplace=True) values.groupby(values.index.month).mean()

标签: python python-3.x dataframe


【解决方案1】:

原始答案 -- 数据与本月平均值之间的差异

我会使用pandas 来完成这项任务,因为它可以很容易地按日期汇总。

首先,让我们制作一个示例数据框并添加月份。

In [45]: import pandas as pd

In [46]: import numpy as np

In [47]: start = datetime.datetime(2011, 1, 1)

In [48]: end = datetime.datetime(2012, 1, 1)

In [49]: df = pd.DataFrame({'date':pd.date_range(start, periods=1000, freq='D'), 'x':np.random.normal(5,1,1000)})
In [84]: df = pd.DataFrame({'date':pd.date_range(start, periods=1000, freq='D'), 'x':np.random.normal(5,1,1000)})

In [86]: df['month'] = df.date.dt.month

In [87]: df.head()
Out[87]:
        date         x  month
0 2011-01-01  5.139113      1
1 2011-01-02  3.774586      1
2 2011-01-03  6.095986      1
3 2011-01-04  5.037072      1
4 2011-01-05  5.871760      1
2011-01-05 2011-01-05  6.308203

现在我们可以使用resamplemean 创建一个包含月平均值的新数据框。

In [58]: monthly_mean = df.resample('M').mean()

In [59]: monthly_mean.head()
Out[59]:
                   x
date
2011-01-31  4.702853
2011-02-28  5.088545
2011-03-31  5.261777
2011-04-30  4.982984
2011-05-31  4.791729

我们可以计算 o

接下来,我们需要将两个数据框连接在一起,以将数据与月平均值对齐。为了使这更容易,我将在每个数据框中创建一个年份和月份列,用于连接/合并。

In [60]: df['month'] = df.index.month

In [61]: monthly_mean['month'] = monthly_mean.index.month

In [62]: df['year'] = df.index.year

In [63]: monthly_mean['year'] = monthly_mean.index.year

In [64]: df_joined = pd.merge(df, monthly_mean, how='left', on=('year', 'month'))

In [65]: df_joined.head()
Out[65]:
        date       x_x  month  year       x_y
0 2011-01-01  5.388197      1  2011  4.702853
1 2011-01-02  6.442878      1  2011  4.702853
2 2011-01-03  5.979076      1  2011  4.702853
3 2011-01-04  2.846689      1  2011  4.702853
4 2011-01-05  5.103524      1  2011  4.702853

最后,可以通过减去列来构造新列。

In [66]: df_joined['month_diff'] = df_joined.x_x - df_joined.x_y

In [67]: df_joined.head()
Out[67]:
        date       x_x  month  year       x_y  month_diff
0 2011-01-01  5.388197      1  2011  4.702853    0.685344
1 2011-01-02  6.442878      1  2011  4.702853    1.740025
2 2011-01-03  5.979076      1  2011  4.702853    1.276223
3 2011-01-04  2.846689      1  2011  4.702853   -1.856164
4 2011-01-05  5.103524      1  2011  4.702853    0.400670

编辑:如果您想要与历史月平均值的差异,请进行以下更改。

添加月份、分组依据和聚合以获得每月平均值。

In [88]: monthly_mean = df.groupby('month').agg('mean')

现在流程像以前一样继续,加入,这次只是通过'month',并计算差异。

In [90]: df_joined = pd.merge(df, monthly_mean, how='left', on='month')

In [91]: df_joined.head()
Out[91]:
        date       x_x  month       x_y
0 2011-01-01  5.139113      1  4.972604
1 2011-01-02  3.774586      1  4.972604
2 2011-01-03  6.095986      1  4.972604
3 2011-01-04  5.037072      1  4.972604
4 2011-01-05  5.871760      1  4.972604

In [92]: df_joined['month_diff'] = df_joined.x_x - df_joined.x_y

In [93]: df_joined.head()
Out[93]:
        date       x_x  month       x_y  month_diff
0 2011-01-01  5.139113      1  4.972604    0.166509
1 2011-01-02  3.774586      1  4.972604   -1.198018
2 2011-01-03  6.095986      1  4.972604    1.123382
3 2011-01-04  5.037072      1  4.972604    0.064468
4 2011-01-05  5.871760      1  4.972604    0.899156

【讨论】:

  • 我有几年时间,即从 1951 年到 2005 年。在我的情况下,我只会得到 12 平均值(整个数据集的月平均值)。现在如何将这些平均值减去每年该月的相应日期。
  • 您的更新问题几乎就在那里,只需要按月加入旧表和新表。
【解决方案2】:

谢谢大家。我能够解决这个问题。
我希望它是正确的。

Anomaly_Values = Data.sub(Data.groupby([Data.index.month]).transform('mean'))

如果解决方案有任何问题,请告诉我。

【讨论】:

    猜你喜欢
    • 2020-05-22
    • 2021-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 2019-03-03
    • 1970-01-01
    • 2012-05-17
    相关资源
    最近更新 更多