首页Python【Python数据分析】6...

【Python数据分析】62.时间序列——重新采样和频率转换2


本系列文章配套代码获取有以下三种途径:

  • 可以在以下网站查看,该网站是使用JupyterLite搭建的web端Jupyter环境,因此无需在本地安装运行环境即可使用,首次运行浏览器需要下载一些配置文件(大约20M):

https://returu.github.io/Python_Data_Analysis/lab/index.html
链接:https://pan.baidu.com/s/1MYkeYeVAIRqbxezQECHwcA?pwd=mnsj 提取码:mnsj
  • 前往GitHub详情页面,单击 code 按钮,选择Download ZIP选项:
https://github.com/returu/Python_Data_Analysis

根据《Python for Data Analysis 3rd Edition》翻译整理

—————————————————–

1.使用区间进行重新采样:

对以区间为索引的数据进行重新采样类似于时间戳的情况:

 1>>> df = pd.DataFrame(np.arange(72).reshape((243)),
2...                      index=pd.period_range("2022-01","2023-12",freq="M"),
3...                      columns=["A""B""C"])
4
5>>> df
6          A   B   C
72022-01   0   1   2
82022-02   3   4   5
92022-03   6   7   8
102022-04   9  10  11
112022-05  12  13  14
122022-06  15  16  17
132022-07  18  19  20
142022-08  21  22  23
152022-09  24  25  26
162022-10  27  28  29
172022-11  30  31  32
182022-12  33  34  35
192023-01  36  37  38
202023-02  39  40  41
212023-03  42  43  44
222023-04  45  46  47
232023-05  48  49  50
242023-06  51  52  53
252023-07  54  55  56
262023-08  57  58  59
272023-09  60  61  62
282023-10  63  64  65
292023-11  66  67  68
302023-12  69  70  71
31
32>>> df_annual = df.resample("A-DEC").max()
33>>> df_annual
34       A   B   C
352022  33  34  35
362023  69  70  71

向上采样更为细致,因为在重新采样之前必须决定新频率中在时间段的哪一端放置数值(与asfreq方法类似)。convention参数默认值为“start”,但也可以是end

 1# Q-DEC:每季度,年末在12月份
2>>> df_annual.resample("Q-DEC").ffill()
3         A   B   C
42022Q1  33  34  35
52022Q2  33  34  35
62022Q3  33  34  35
72022Q4  33  34  35
82023Q1  69  70  71
92023Q2  69  70  71
102023Q3  69  70  71
112023Q4  69  70  71
12
13>>> df_annual.resample("Q-DEC" , convention="end").ffill()
14         A   B   C
152022Q4  33  34  35
162023Q1  33  34  35
172023Q2  33  34  35
182023Q3  33  34  35
192023Q4  69  70  71
20
21>>> df_annual.resample("Q-DEC").asfreq()
22           A     B     C
232022Q1  33.0  34.0  35.0
242022Q2   NaN   NaN   NaN
252022Q3   NaN   NaN   NaN
262022Q4   NaN   NaN   NaN
272023Q1  69.0  70.0  71.0
282023Q2   NaN   NaN   NaN
292023Q3   NaN   NaN   NaN
302023Q4   NaN   NaN   NaN
31
32>>> df_annual.resample("Q-DEC" , convention="end").asfreq()
33           A     B     C
342022Q4  33.0  34.0  35.0
352023Q1   NaN   NaN   NaN
362023Q2   NaN   NaN   NaN
372023Q3   NaN   NaN   NaN
382023Q4  69.0  70.0  71.0

由于区间指定的是时间范围,向上采样和向下采样就更为严格:

  • 在向下采样中,目标频率必须是原频率的子区间;

  • 在向上采样中,目标频率必须是原频率的父区间。

如果不满足上述规则,将引发异常。

这主要会影响每季度、每年和每周的频率。例如,根据Q-MAR定义为时间范围将只和A-MARA-JUNA-SEPA-DEC保持一致。

 1>>> df_annual.resample("Q-MAR").ffill()
2         A   B   C
32022Q4  33  34  35
42023Q1  33  34  35
52023Q2  33  34  35
62023Q3  33  34  35
72023Q4  69  70  71
82024Q1  69  70  71
92024Q2  69  70  71
102024Q3  69  70  71

2.分组的时间重新采样:

对于时间序列数据,重采样方法在语义上是一种基于时间分段的分组操作。

以下面DataFrame为例,我们可以按“time”列进行索引,然后重新采样::

 1>>> times = pd.date_range("2022-12-12 00:00", freq="1h", periods=15)
2>>> times
3DatetimeIndex(['2022-12-12 00:00:00''2022-12-12 01:00:00',
4               '2022-12-12 02:00:00''2022-12-12 03:00:00',
5               '2022-12-12 04:00:00''2022-12-12 05:00:00',
6               '2022-12-12 06:00:00''2022-12-12 07:00:00',
7               '2022-12-12 08:00:00''2022-12-12 09:00:00',
8               '2022-12-12 10:00:00''2022-12-12 11:00:00',
9               '2022-12-12 12:00:00''2022-12-12 13:00:00',
10               '2022-12-12 14:00:00'],
11              dtype='datetime64[ns]', freq='H')
12
13>>> df = pd.DataFrame({"time": times,"value": np.arange(15)})
14>>> df
15                  time  value
160  2022-12-12 00:00:00      0
171  2022-12-12 01:00:00      1
182  2022-12-12 02:00:00      2
193  2022-12-12 03:00:00      3
204  2022-12-12 04:00:00      4
215  2022-12-12 05:00:00      5
226  2022-12-12 06:00:00      6
237  2022-12-12 07:00:00      7
248  2022-12-12 08:00:00      8
259  2022-12-12 09:00:00      9
2610 2022-12-12 10:00:00     10
2711 2022-12-12 11:00:00     11
2812 2022-12-12 12:00:00     12
2913 2022-12-12 13:00:00     13
3014 2022-12-12 14:00:00     14
31
32# 按"time"进行索引,然后重新采样
33>>> df.set_index("time").resample("5h").count()
34                     value
35time
362022-12-12 00:00:00      5
372022-12-12 05:00:00      5
382022-12-12 10:00:00      5

如果一个 DataFrame 包含多个时间序列,并按一个附加的分组键列(本例为“key”列)进行了标记。为了对“key”列的每个值进行相同的重采样,需要引入 pandas.Grouper 对象。

需要注意的是,使用 pandas.Grouper 的一个限制是时间必须是 Series 或 DataFrame 的索引。

 1>>> df2 = pd.DataFrame({"time": times.repeat(3),"key": np.tile(["a""b""c"], 15),"value": np.arange(15 * 3.)})
2>>> df2
3                  time key  value
40  2022-12-12 00:00:00   a    0.0
51  2022-12-12 00:00:00   b    1.0
62  2022-12-12 00:00:00   c    2.0
73  2022-12-12 01:00:00   a    3.0
84  2022-12-12 01:00:00   b    4.0
95  2022-12-12 01:00:00   c    5.0
106  2022-12-12 02:00:00   a    6.0
117  2022-12-12 02:00:00   b    7.0
128  2022-12-12 02:00:00   c    8.0
139  2022-12-12 03:00:00   a    9.0
1410 2022-12-12 03:00:00   b   10.0
1511 2022-12-12 03:00:00   c   11.0
1612 2022-12-12 04:00:00   a   12.0
1713 2022-12-12 04:00:00   b   13.0
1814 2022-12-12 04:00:00   c   14.0
1915 2022-12-12 05:00:00   a   15.0
2016 2022-12-12 05:00:00   b   16.0
2117 2022-12-12 05:00:00   c   17.0
2218 2022-12-12 06:00:00   a   18.0
2319 2022-12-12 06:00:00   b   19.0
2420 2022-12-12 06:00:00   c   20.0
2521 2022-12-12 07:00:00   a   21.0
2622 2022-12-12 07:00:00   b   22.0
2723 2022-12-12 07:00:00   c   23.0
2824 2022-12-12 08:00:00   a   24.0
2925 2022-12-12 08:00:00   b   25.0
3026 2022-12-12 08:00:00   c   26.0
3127 2022-12-12 09:00:00   a   27.0
3228 2022-12-12 09:00:00   b   28.0
3329 2022-12-12 09:00:00   c   29.0
3430 2022-12-12 10:00:00   a   30.0
3531 2022-12-12 10:00:00   b   31.0
3632 2022-12-12 10:00:00   c   32.0
3733 2022-12-12 11:00:00   a   33.0
3834 2022-12-12 11:00:00   b   34.0
3935 2022-12-12 11:00:00   c   35.0
4036 2022-12-12 12:00:00   a   36.0
4137 2022-12-12 12:00:00   b   37.0
4238 2022-12-12 12:00:00   c   38.0
4339 2022-12-12 13:00:00   a   39.0
4440 2022-12-12 13:00:00   b   40.0
4541 2022-12-12 13:00:00   c   41.0
4642 2022-12-12 14:00:00   a   42.0
4743 2022-12-12 14:00:00   b   43.0
4844 2022-12-12 14:00:00   c   44.0
49
50# pandas.Grouper 对象
51>>> time_key = pd.Grouper(freq="5h")
52>>> time_key
53TimeGrouper(freq=<5 * Hours>, axis=0, sort=True, closed='left', label='left', how='mean', convention='e', origin='start_day')
54
55# 设置时间索引,按"key"和 time_key 分组,并聚合:
56>>> resampled = df2.set_index("time").groupby(["key", time_key]).max()
57>>> resampled
58                         value
59key time
60a   2022-12-12 00:00:00   12.0
61    2022-12-12 05:00:00   27.0
62    2022-12-12 10:00:00   42.0
63b   2022-12-12 00:00:00   13.0
64    2022-12-12 05:00:00   28.0
65    2022-12-12 10:00:00   43.0
66c   2022-12-12 00:00:00   14.0
67    2022-12-12 05:00:00   29.0
68    2022-12-12 10:00:00   44.0
69
70>>> resampled.reset_index()
71  key                time  value
720   a 2022-12-12 00:00:00   12.0
731   a 2022-12-12 05:00:00   27.0
742   a 2022-12-12 10:00:00   42.0
753   b 2022-12-12 00:00:00   13.0
764   b 2022-12-12 05:00:00   28.0
775   b 2022-12-12 10:00:00   43.0
786   c 2022-12-12 00:00:00   14.0
797   c 2022-12-12 05:00:00   29.0
808   c 2022-12-12 10:00:00   44.0


本篇文章来源于微信公众号: 码农设计师

RELATED ARTICLES

欢迎留下您的宝贵建议

Please enter your comment!
Please enter your name here

- Advertisment -

Most Popular

Recent Comments