CSDN 課程推薦:《邁向數據科學家:帶你玩轉Python數據分析》,講師齊偉,蘇州研途教育科技有限公司CTO,蘇州大學應用統計專業碩士生指導委員會委員;已出版《跟老齊學Python:輕鬆入門》《跟老齊學Python:Django實戰》、《跟老齊學Python:數據分析》和《Python大學實用教程》暢銷圖書。
Pandas 系列文章:
- Python 數據分析三劍客之 Pandas(一):認識 Pandas 及其 Series、DataFrame 對象
- Python 數據分析三劍客之 Pandas(二):Index 索引對象以及各種索引操作
- Python 數據分析三劍客之 Pandas(三):算術運算與缺失值的處理
- Python 數據分析三劍客之 Pandas(四):函數應用、映射、排序和層級索引
- Python 數據分析三劍客之 Pandas(五):統計計算與統計描述
- Python 數據分析三劍客之 Pandas(六):GroupBy 數據分裂、應用與合併
- Python 數據分析三劍客之 Pandas(七):合併數據集
- Python 數據分析三劍客之 Pandas(八):數據重塑、重複數據處理與數據替換
- Python 數據分析三劍客之 Pandas(九):時間序列
- Python 數據分析三劍客之 Pandas(十):數據讀寫
另有 NumPy、Matplotlib 系列文章已更新完畢,歡迎關注:
- NumPy 系列文章:https://itrhx.blog.csdn.net/category_9780393.html
- Matplotlib 系列文章:https://itrhx.blog.csdn.net/category_9780418.html
推薦學習資料與網站(博主參與部分文檔翻譯):
- NumPy 官方中文網:https://www.numpy.org.cn/
- Pandas 官方中文網:https://www.pypandas.cn/
- Matplotlib 官方中文網:https://www.matplotlib.org.cn/
- NumPy、Matplotlib、Pandas 速查表:https://github.com/TRHX/Python-quick-reference-table
文章目錄
這裏是一段防爬蟲文本,請讀者忽略。
本文原創首發於 CSDN,作者 TRHX。
博客首頁:https://itrhx.blog.csdn.net/
本文鏈接:https://itrhx.blog.csdn.net/article/details/106947061
未經授權,禁止轉載!惡意轉載,後果自負!尊重原創,遠離剽竊!
【01x00】時間序列
官網對於時間序列的介紹:https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html
時間序列(time series)是一種重要的結構化數據形式,應用於多個領域,包括金融學、經濟學、生態學、神經科學、物理學等。在多個時間點觀察或測量到的任何事物都可以形成一段時間序列。很多時間序列是固定頻率的,也就是說,數據點是根據某種規律定期出現的(比如每15秒、每5分鐘、每月出現一次)。時間序列也可以是不定期的,沒有固定的時間單位或單位之間的偏移量。時間序列數據的意義取決於具體的應用場景,主要有以下幾種:
-
時間戳(timestamp),表示某個具體的時間點,例如 2020-6-24 15:30;
-
固定週期(period),表示某個時間週期,例如 2020-01;
-
時間間隔(timedelta),持續時間,即兩個日期或時間之間的差異。
-
針對時間戳數據,Pandas 提供了 Timestamp 類型。它本質上是 Python 的原生 datetime 類型的替代品,但是在性能更好的 numpy.datetime64 類型的基礎上創建。對應的索引數據結構是 DatetimeIndex。
-
針對時間週期數據,Pandas 提供了 Period 類型。這是利用 numpy.datetime64 類型將固定頻率的時間間隔進行編碼。對應的索引數據結構是 PeriodIndex。
-
針對時間增量或持續時間,Pandas 提供了 Timedelta 類型。Timedelta 是一種代替 Python 原生datetime.timedelta 類型的高性能數據結構,同樣是基於 numpy.timedelta64 類型。對應的索引數據結構是 TimedeltaIndex。
【02x00】Timestamp 時間戳
【02x01】pandas.Timestamp
在 pandas 中,pandas.Timestamp
方法用來代替 Python 中的 datetime.datetime
方法。
Timestamp 與 Python 的 Datetime 等效,在大多數情況下都可以互換。 此類型用於組成 DatetimeIndex 以及 Pandas 中其他面向時間序列的數據結構。
官方文檔:https://pandas.pydata.org/docs/reference/api/pandas.Timestamp.html
基本語法:
class pandas.Timestamp(ts_input=<object object>,
freq=None, tz=None, unit=None,
year=None, month=None, day=None,
hour=None, minute=None, second=None,
microsecond=None, nanosecond=None, tzinfo=None)
常用參數:
參數 | 描述 |
---|---|
ts_input | 要轉換爲時間戳的對象,可以是 datetime-like,str,int,float 類型 |
freq | 時間戳將具有的偏移量,可以是 str,日期偏移量類型,取值參見【02x02】freq 頻率部分取值 |
tz | 時間戳將具有的時區 |
unit | 如果 ts_input 是整數或浮點數,該參數用於設置其單位(D、s、ms、us、ns) |
簡單示例:
>>> import pandas as pd
>>> pd.Timestamp('2017-01-01T12')
Timestamp('2017-01-01 12:00:00')
設置 unit='s'
,即待轉換對象單位爲秒:
>>> import pandas as pd
>>> pd.Timestamp(1513393355.5, unit='s')
Timestamp('2017-12-16 03:02:35.500000')
使用 tz
參數設置時區:
>>> import pandas as pd
>>> pd.Timestamp(1513393355, unit='s', tz='US/Pacific')
Timestamp('2017-12-15 19:02:35-0800', tz='US/Pacific')
單獨設置年月日:
>>> import pandas as pd
>>> pd.Timestamp(year=2020, month=6, day=24, hour=12)
Timestamp('2020-06-24 12:00:00')
【02x02】freq 頻率部分取值
完整取值參見官方文檔:https://pandas.pydata.org/docs/user_guide/timeseries.html#timeseries-offset-aliases
參數 | 類型 | 描述 |
---|---|---|
D | Day | 每日曆日 |
B | BusinessDay | 每工作日 |
H | Hour | 每小時 |
T 或 min | Minute | 每分 |
S | Second | 每秒 |
L 或 ms | Milli | 每毫秒(即每千分之一秒) |
U | Micro | 每微秒(即每百萬分之一秒) |
M | MonthEnd | 每月最後一個日曆日 |
BM | BusinessMonthEnd | 每月最後一個工作日 |
MS | MonthBegin | 每月第一個日曆日 |
BMS | BusinessMonthBegin | 每月第一個工作日 |
W-MON、W-TUE… | Week | 從指定的星期幾(MON、TUE、 WED、THU、FR、SAT、SUN)開始算起,每週 |
WoM-1MON、WOM-2MON… | WeekOfMonth | 產生每月第一、第二、第三或第四周的星期幾。例如,WoM-3FRI 表示每月第3個星期五 |
Q-JAN、Q-FEB… | QuarterEnd | 對於以指定月份(JAN、FEB、MAR、APR、MAY、JUN、JUL、AUG、SEP、OCT、NOV、DEC)結束的年度,每季度最後一月的最後個日曆日 |
BQ-JAN、BQ-FEB… | BusinessQuarterEnd | 對於以指定月份結束的年度,每季度最後一月的最後一個工作日 |
QS-JAN、QS-FEB… | QuarterBegin | 對於以指定月份結束的年度,每季度最後一月的第一個日曆日 |
BQS-JAN、 BQS-FEB… | BusinessQuarterBegin | 對於以指定月份結束的年度,每季度最後一月的第一個工作日 |
A-JAN、A-FEB… | YearEnd | 每年指定月份(JAN、FEB、MAR、APR、MAY、JUN、JUL、AUG、SEP、 OCT、NOV、DEC)的最後一個日曆日 |
BA-JAN、BA-FEB… | BusinessYearEnd | 每年指定月份的最後一個工作日 |
AS-JAN、AS-FEB… | YearBegin | 每年指定月份的第一個歷日日 |
BAS-JAN、BAS-FEB… | BusinessYearBegin | 每年指定月份的第一個工作日 |
【02x03】to_datetime
在 Python 中,datetime 庫提供了日期和時間處理方法,利用 str
或 strftime
方法可以將 datetime 對象轉化成字符串,具體用法可參見【Python 標準庫學習】日期和時間處理庫 — datetime。
>>> from datetime import datetime
>>> stamp = datetime(2020, 6, 24)
>>> stamp
datetime.datetime(2020, 6, 24, 0, 0)
>>>
>>> str(stamp)
'2020-06-24 00:00:00'
>>>
>>> stamp.strftime('%Y-%m-%d')
'2020-06-24'
在 pandas 中 to_datetime 方法可以將字符串解析成多種不同的 Timestamp(時間戳) 對象:
>>> import pandas as pd
>>> datestrs = '2011-07-06 12:00:00'
>>> type(datestrs)
<class 'str'>
>>>
>>> pd.to_datetime(datestrs)
Timestamp('2011-07-06 12:00:00')
基本語法:
pandas.to_datetime(arg, errors='raise', dayfirst=False,
yearfirst=False, utc=None, format=None,
exact=True, unit=None, infer_datetime_format=False,
origin='unix', cache=True)
官方文檔:https://pandas.pydata.org/docs/reference/api/pandas.to_datetime.html
常用參數:
參數 | 描述 |
---|---|
arg | 要轉換爲日期時間的對象,可以接受 int, float, str, datetime, list, tuple, 1-d array, Series DataFrame/dict-like 類型 |
errors | 如果字符串不滿足時間戳的形式,是否會發生異常ignore :不引發異常,返回原始輸入;raise :無效解析將引發異常(默認);coerce :無效解析將被設置爲NaT |
dayfirst | bool 類型,默認 False,如果 arg 是 str 或列表,是否首先解析爲日期 例如 dayfirst 爲 True, 10/11/12 被解析爲 2012-11-10 ,爲 False 則解析爲 2012-10-11 |
yearfirst | bool 類型,默認 False,如果 arg 是 str 或列表,是否首先解析爲年份 例如 dayfirst 爲 True, 10/11/12 被解析爲 2010-11-12 ,爲 False 則解析爲 2012-10-11 如果 dayfirst 和 yearfirst 都爲 True,則優先 yearfirst |
utc | bool 類型,是否轉換爲協調世界時,默認 None |
format | 格式化時間,如 21/2/20 16:10 使用 %d/%m/%y %H:%M 會被解析爲 2020-02-21 16:10:00 符號含義常見文章:【Python 標準庫學習】日期和時間處理庫 — datetime 或者官方文檔 |
exact | 如果爲 True,則需要精確的格式匹配。如果爲 False,則允許格式與目標字符串中的任何位置匹配 |
unit | 如果 arg 是整數或浮點數,該參數用於設置其單位(D、s、ms、us、ns) |
簡單應用:
>>> import pandas as pd
>>> obj = pd.DataFrame({'year': [2015, 2016], 'month': [2, 3], 'day': [4, 5]})
>>> obj
year month day
0 2015 2 4
1 2016 3 5
>>>
>>> pd.to_datetime(obj)
0 2015-02-04
1 2016-03-05
dtype: datetime64[ns]
設置 format
和 errors
參數:
>>> import pandas as pd
>>> pd.to_datetime('13000101', format='%Y%m%d', errors='ignore')
datetime.datetime(1300, 1, 1, 0, 0)
>>>
>>> pd.to_datetime('13000101', format='%Y%m%d', errors='coerce')
NaT
>>>
>>> pd.to_datetime('13000101', format='%Y%m%d', errors='raise')
Traceback (most recent call last):
...
pandas._libs.tslibs.np_datetime.OutOfBoundsDatetime: Out of bounds nanosecond timestamp: 1300-01-01 00:00:00
設置 unit
參數:
>>> import pandas as pd
>>> pd.to_datetime(1490195805, unit='s')
Timestamp('2017-03-22 15:16:45')
>>>
>>> pd.to_datetime(1490195805433502912, unit='ns')
Timestamp('2017-03-22 15:16:45.433502912')
【02x04】date_range
pandas.date_range
方法可用於根據指定的頻率生成指定長度的 DatetimeIndex。
基本語法:
pandas.date_range(start=None, end=None, periods=None, freq=None,
tz=None, normalize=False, name=None, closed=None,
**kwargs) → pandas.core.indexes.datetimes.DatetimeIndex
官方文檔:https://pandas.pydata.org/docs/reference/api/pandas.date_range.html
參數 | 描述 |
---|---|
start | 開始日期 |
end | 結束日期 |
periods | int 類型,要生成的時段數(天) |
freq | 頻率字符串,即按照某種特定的頻率來生成日期,取值參見【02x02】freq 頻率部分取值 |
tz | 設置時區,例如 “Asia/Hong_Kong” |
normalize | bool 類型,默認 False,是否在生成日期之前對其進行規範化(僅保留年月日) |
name | 結果 DatetimeIndex 的名稱 |
closed | None :默認值,同時保留開始日期和結束日期'left' :保留開始日期,不保留結束日期'right' :保留結束日期,不保留開始日期 |
簡單示例:
>>> import pandas as pd
>>> pd.date_range(start='1/1/2018', end='1/08/2018')
DatetimeIndex(['2018-01-01', '2018-01-02', '2018-01-03', '2018-01-04',
'2018-01-05', '2018-01-06', '2018-01-07', '2018-01-08'],
dtype='datetime64[ns]', freq='D')
指定 periods
參數:
>>> import pandas as pd
>>> pd.date_range(start='2012-04-01', periods=20)
DatetimeIndex(['2012-04-01', '2012-04-02', '2012-04-03', '2012-04-04',
'2012-04-05', '2012-04-06', '2012-04-07', '2012-04-08',
'2012-04-09', '2012-04-10', '2012-04-11', '2012-04-12',
'2012-04-13', '2012-04-14', '2012-04-15', '2012-04-16',
'2012-04-17', '2012-04-18', '2012-04-19', '2012-04-20'],
dtype='datetime64[ns]', freq='D')
>>>
>>> pd.date_range(end='2012-06-01', periods=20)
DatetimeIndex(['2012-05-13', '2012-05-14', '2012-05-15', '2012-05-16',
'2012-05-17', '2012-05-18', '2012-05-19', '2012-05-20',
'2012-05-21', '2012-05-22', '2012-05-23', '2012-05-24',
'2012-05-25', '2012-05-26', '2012-05-27', '2012-05-28',
'2012-05-29', '2012-05-30', '2012-05-31', '2012-06-01'],
dtype='datetime64[ns]', freq='D')
>>>
>>> pd.date_range(start='2018-04-24', end='2018-04-27', periods=3)
DatetimeIndex(['2018-04-24 00:00:00', '2018-04-25 12:00:00', '2018-04-27 00:00:00'],
dtype='datetime64[ns]', freq=None)
>>>
>>> pd.date_range(start='2018-04-24', end='2018-04-28', periods=3)
DatetimeIndex(['2018-04-24', '2018-04-26', '2018-04-28'], dtype='datetime64[ns]', freq=None)
指定 freq='M'
會按照每月最後一個日曆日的頻率生成日期,指定 freq='3M'
會每隔3個月按照每月最後一個日曆日的頻率生成日期:
>>> import pandas as pd
>>> pd.date_range(start='1/1/2018', periods=5, freq='M')
DatetimeIndex(['2018-01-31', '2018-02-28', '2018-03-31', '2018-04-30',
'2018-05-31'],
dtype='datetime64[ns]', freq='M')
>>>
>>> pd.date_range(start='1/1/2018', periods=5, freq='3M')
DatetimeIndex(['2018-01-31', '2018-04-30', '2018-07-31', '2018-10-31',
'2019-01-31'],
dtype='datetime64[ns]', freq='3M')
>>>
使用 tz
參數設置時區:
>>> import pandas as pd
>>> pd.date_range(start='1/1/2018', periods=5, tz='Asia/Tokyo')
DatetimeIndex(['2018-01-01 00:00:00+09:00', '2018-01-02 00:00:00+09:00',
'2018-01-03 00:00:00+09:00', '2018-01-04 00:00:00+09:00',
'2018-01-05 00:00:00+09:00'],
dtype='datetime64[ns, Asia/Tokyo]', freq='D')
>>>
>>> pd.date_range(start='6/24/2020', periods=5, tz='Asia/Hong_Kong')
DatetimeIndex(['2020-06-24 00:00:00+08:00', '2020-06-25 00:00:00+08:00',
'2020-06-26 00:00:00+08:00', '2020-06-27 00:00:00+08:00',
'2020-06-28 00:00:00+08:00'],
dtype='datetime64[ns, Asia/Hong_Kong]', freq='D')
設置 normalize
參數,在生成時間戳之前對其進行格式化操作:
>>> import pandas as pd
>>> pd.date_range('2020-06-24 12:56:31', periods=5, normalize=True)
DatetimeIndex(['2020-06-24', '2020-06-25', '2020-06-26', '2020-06-27',
'2020-06-28'],
dtype='datetime64[ns]', freq='D')
設置 closed
參數:
>>> import pandas as pd
>>> pd.date_range(start='2020-06-20', end='2020-06-24', closed=None)
DatetimeIndex(['2020-06-20', '2020-06-21', '2020-06-22', '2020-06-23',
'2020-06-24'],
dtype='datetime64[ns]', freq='D')
>>>
>>> pd.date_range(start='2020-06-20', end='2020-06-24', closed='left')
DatetimeIndex(['2020-06-20', '2020-06-21', '2020-06-22', '2020-06-23'], dtype='datetime64[ns]', freq='D')
>>>
>>> pd.date_range(start='2020-06-20', end='2020-06-24', closed='right')
DatetimeIndex(['2020-06-21', '2020-06-22', '2020-06-23', '2020-06-24'], dtype='datetime64[ns]', freq='D')
【02x05】索引與切片
Pandas 最基本的時間序列類型就是以時間戳(通常以 Python 字符串或 datatime 對象表示)爲索引的Series,這些 datetime 對象實際上是被放在 DatetimeIndex 中的,可以使用類似 pandas.Series 對象的切片方法對其進行索引:
>>> import pandas as pd
>>> import numpy as np
>>> dates = [datetime(2011, 1, 2), datetime(2011, 1, 5),
datetime(2011, 1, 7), datetime(2011, 1, 8),
datetime(2011, 1, 10), datetime(2011, 1, 12)]
>>> obj = pd.Series(np.random.randn(6), index=dates)
>>>
>>> obj
2011-01-02 -0.407110
2011-01-05 -0.186661
2011-01-07 -0.731080
2011-01-08 0.860970
2011-01-10 1.929973
2011-01-12 -0.168599
dtype: float64
>>>
>>> obj.index
DatetimeIndex(['2011-01-02', '2011-01-05', '2011-01-07', '2011-01-08',
'2011-01-10', '2011-01-12'],
dtype='datetime64[ns]', freq=None)
>>>
>>> obj.index[0]
Timestamp('2011-01-02 00:00:00')
>>>
>>> obj.index[0:3]
DatetimeIndex(['2011-01-02', '2011-01-05', '2011-01-07'], dtype='datetime64[ns]', freq=None)
另外還可以傳入一個可以被解釋爲日期的字符串,或者只需傳入“年”或“年月”即可輕鬆選取數據的切片:
>>> import pandas as pd
>>> import numpy as np
>>> obj = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))
>>> obj
2000-01-01 -1.142284
2000-01-02 1.198785
2000-01-03 2.466909
2000-01-04 -0.086728
2000-01-05 -0.978437
...
2002-09-22 -0.252240
2002-09-23 0.148561
2002-09-24 -1.330409
2002-09-25 -0.673471
2002-09-26 -0.253271
Freq: D, Length: 1000, dtype: float64
>>>
>>> obj['26/9/2002']
-0.25327100684233356
>>>
>>> obj['2002']
2002-01-01 1.058715
2002-01-02 0.900859
2002-01-03 1.993508
2002-01-04 -0.103211
2002-01-05 -0.950090
...
2002-09-22 -0.252240
2002-09-23 0.148561
2002-09-24 -1.330409
2002-09-25 -0.673471
2002-09-26 -0.253271
Freq: D, Length: 269, dtype: float64
>>>
>>> obj['2002-09']
2002-09-01 -0.995528
2002-09-02 0.501528
2002-09-03 -0.486753
2002-09-04 -1.083906
2002-09-05 1.458975
2002-09-06 -1.331685
2002-09-07 0.195338
2002-09-08 -0.429613
2002-09-09 1.125823
2002-09-10 1.607051
2002-09-11 0.530387
2002-09-12 -0.015938
2002-09-13 1.781043
2002-09-14 -0.277123
2002-09-15 0.344569
2002-09-16 -1.010810
2002-09-17 0.463001
2002-09-18 1.883636
2002-09-19 0.274520
2002-09-20 0.624184
2002-09-21 -1.203057
2002-09-22 -0.252240
2002-09-23 0.148561
2002-09-24 -1.330409
2002-09-25 -0.673471
2002-09-26 -0.253271
Freq: D, dtype: float64
>>>
>>> obj['20/9/2002':'26/9/2002']
2002-09-20 0.624184
2002-09-21 -1.203057
2002-09-22 -0.252240
2002-09-23 0.148561
2002-09-24 -1.330409
2002-09-25 -0.673471
2002-09-26 -0.253271
Freq: D, dtype: float64
【02x06】移動數據與數據偏移
移動(shifting)指的是沿着時間軸將數據前移或後移。Series 和 DataFrame 都有一個 shift 方法用於執行單純的前移或後移操作,保持索引不變:
>>> import pandas as pd
>>> import numpy as np
>>> obj = pd.Series(np.random.randn(4),
index=pd.date_range('1/1/2000', periods=4, freq='M'))
>>> obj
2000-01-31 -0.100217
2000-02-29 1.177834
2000-03-31 -0.644353
2000-04-30 -1.954679
Freq: M, dtype: float64
>>>
>>> obj.shift(2)
2000-01-31 NaN
2000-02-29 NaN
2000-03-31 -0.100217
2000-04-30 1.177834
Freq: M, dtype: float64
>>>
>>> obj.shift(-2)
2000-01-31 -0.644353
2000-02-29 -1.954679
2000-03-31 NaN
2000-04-30 NaN
Freq: M, dtype: float64
因爲簡單的移位操作不會修改索引,所以部分數據會被丟棄並引入 NaN(缺失值)。因此,如果頻率已知,則可以將其傳給 shift 以便實現對時間戳進行位移而不是對數據進行簡單位移:
>>> import pandas as pd
>>> import numpy as np
>>> obj = pd.Series(np.random.randn(4),
index=pd.date_range('1/1/2000', periods=4, freq='M'))
>>> obj
2000-01-31 -0.100217
2000-02-29 1.177834
2000-03-31 -0.644353
2000-04-30 -1.954679
Freq: M, dtype: float64
>>>
>>> obj.shift(2, freq='M')
2000-03-31 -0.100217
2000-04-30 1.177834
2000-05-31 -0.644353
2000-06-30 -1.954679
Freq: M, dtype: float64
Pandas 中的頻率是由一個基礎頻率(base frequency)和一個乘數組成的。基礎頻率通常以一個字符串別名表示,比如 "M"
表示每月,"H"
表示每小時。對於每個基礎頻率,都有一個被稱爲日期偏移量(date offset)的對象與之對應。例如,按小時計算的頻率可以用 Hour
類表示:
>>> from pandas.tseries.offsets import Hour, Minute
>>> hour = Hour()
>>> hour
<Hour>
>>>
>>> four_hours = Hour(4)
>>> four_hours
<4 * Hours>
一般來說,無需明確創建這樣的對象,只需使用諸如 "H"
或 "4H"
這樣的字符串別名即可。在基礎頻率前面放上一個整數即可創建倍數:
>>> import pandas as pd
>>> pd.date_range('2000-01-01', '2000-01-03 23:59', freq='4h')
DatetimeIndex(['2000-01-01 00:00:00', '2000-01-01 04:00:00',
'2000-01-01 08:00:00', '2000-01-01 12:00:00',
'2000-01-01 16:00:00', '2000-01-01 20:00:00',
'2000-01-02 00:00:00', '2000-01-02 04:00:00',
'2000-01-02 08:00:00', '2000-01-02 12:00:00',
'2000-01-02 16:00:00', '2000-01-02 20:00:00',
'2000-01-03 00:00:00', '2000-01-03 04:00:00',
'2000-01-03 08:00:00', '2000-01-03 12:00:00',
'2000-01-03 16:00:00', '2000-01-03 20:00:00'],
dtype='datetime64[ns]', freq='4H')
大部分偏移量對象都可通過加法進行連接:
>>> from pandas.tseries.offsets import Hour, Minute
>>> Hour(2) + Minute(30)
<150 * Minutes>
對於 freq
參數也可以傳入頻率字符串(如 "2h30min"
),這種字符串可以被高效地解析爲等效的表達式:
>>> import pandas as pd
>>> pd.date_range('2000-01-01', periods=10, freq='1h30min')
DatetimeIndex(['2000-01-01 00:00:00', '2000-01-01 01:30:00',
'2000-01-01 03:00:00', '2000-01-01 04:30:00',
'2000-01-01 06:00:00', '2000-01-01 07:30:00',
'2000-01-01 09:00:00', '2000-01-01 10:30:00',
'2000-01-01 12:00:00', '2000-01-01 13:30:00'],
dtype='datetime64[ns]', freq='90T')
這種偏移量還可以用在 datetime 或 Timestamp 對象上:
>>> from pandas.tseries.offsets import Day, MonthEnd
>>> now = datetime(2011, 11, 17)
>>> now + 3 * Day()
Timestamp('2011-11-20 00:00:00')
如果加的是錨點偏移量,比如 MonthEnd,第一次增量會將原日期向前滾動到符合頻率規則的下一個日期:
>>> from pandas.tseries.offsets import Day, MonthEnd
>>> now = datetime(2011, 11, 17)
>>> now + MonthEnd()
Timestamp('2011-11-30 00:00:00')
>>> now + MonthEnd(2)
Timestamp('2011-12-31 00:00:00')
通過錨點偏移量的 rollforward 和 rollback 方法,可明確地將日期向前或向後滾動:
>>> from pandas.tseries.offsets import Day, MonthEnd
>>> now = datetime(2011, 11, 17)
>>> offset = MonthEnd()
>>> offset.rollforward(now)
Timestamp('2011-11-30 00:00:00')
>>> offset.rollback(now)
Timestamp('2011-10-31 00:00:00')
與 groupby
方法結合使用:
>>> import pandas as pd
>>> import numpy as np
>>> from pandas.tseries.offsets import Day, MonthEnd
>>> obj = pd.Series(np.random.randn(20),
index=pd.date_range('1/15/2000', periods=20, freq='4d'))
>>> obj
2000-01-15 -0.591729
2000-01-19 -0.775844
2000-01-23 -0.745603
2000-01-27 -0.076439
2000-01-31 1.796417
2000-02-04 -0.500349
2000-02-08 0.515851
2000-02-12 -0.344171
2000-02-16 0.419657
2000-02-20 0.307288
2000-02-24 0.115113
2000-02-28 -0.362585
2000-03-03 1.074892
2000-03-07 1.111366
2000-03-11 0.949910
2000-03-15 -1.535727
2000-03-19 0.545944
2000-03-23 -0.810139
2000-03-27 -1.260627
2000-03-31 -0.128403
Freq: 4D, dtype: float64
>>>
>>> offset = MonthEnd()
>>> obj.groupby(offset.rollforward).mean()
2000-01-31 -0.078640
2000-02-29 0.021543
2000-03-31 -0.006598
dtype: float64
【02x07】時區處理
在 Python 中,時區信息來自第三方庫 pytz,使用 pytz.common_timezones
方法可以查看所有的時區名稱,使用 pytz.timezone
方法從 pytz 中獲取時區對象:
>>> import pytz
>>> pytz.common_timezones
['Africa/Abidjan', 'Africa/Accra', 'Africa/Addis_Ababa', ..., 'UTC']
>>>
>>> tz = pytz.timezone('Asia/Shanghai')
>>> tz
<DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD> # 表示與 UTC 時間相差8小時6分
在 date_range
方法中,tz
參數用於指定時區,默認爲 None,可以使用 tz_localize
方法將其進行本地化時區轉換,如下示例中,將無時區轉本地化 UTC 時區:
>>> import pandas as pd
>>> import numpy as np
>>> rng = pd.date_range('3/9/2012 9:30', periods=6, freq='D')
>>> ts = pd.Series(np.random.randn(len(rng)), index=rng)
>>> ts
2012-03-09 09:30:00 -1.527913
2012-03-10 09:30:00 -1.116101
2012-03-11 09:30:00 0.359358
2012-03-12 09:30:00 -0.475920
2012-03-13 09:30:00 -0.336570
2012-03-14 09:30:00 -1.075952
Freq: D, dtype: float64
>>>
>>> print(ts.index.tz)
None
>>>
>>> ts_utc = ts.tz_localize('UTC')
>>> ts_utc
2012-03-09 09:30:00+00:00 -1.527913
2012-03-10 09:30:00+00:00 -1.116101
2012-03-11 09:30:00+00:00 0.359358
2012-03-12 09:30:00+00:00 -0.475920
2012-03-13 09:30:00+00:00 -0.336570
2012-03-14 09:30:00+00:00 -1.075952
Freq: D, dtype: float64
>>>
>>> ts_utc.index
DatetimeIndex(['2012-03-09 09:30:00+00:00', '2012-03-10 09:30:00+00:00',
'2012-03-11 09:30:00+00:00', '2012-03-12 09:30:00+00:00',
'2012-03-13 09:30:00+00:00', '2012-03-14 09:30:00+00:00'],
dtype='datetime64[ns, UTC]', freq='D')
時間序列被本地化到某個特定時區後,就可以用 tz_convert
方法將其轉換到別的時區了:
>>> import pandas as pd
>>> import numpy as np
>>> rng = pd.date_range('3/9/2012 9:30', periods=6, freq='D')
>>> ts = pd.Series(np.random.randn(len(rng)), index=rng)
>>> ts
2012-03-09 09:30:00 0.480303
2012-03-10 09:30:00 -1.461039
2012-03-11 09:30:00 -1.512749
2012-03-12 09:30:00 -2.185421
2012-03-13 09:30:00 1.657845
2012-03-14 09:30:00 0.175633
Freq: D, dtype: float64
>>>
>>> ts.tz_localize('UTC').tz_convert('Asia/Shanghai')
2012-03-09 17:30:00+08:00 0.480303
2012-03-10 17:30:00+08:00 -1.461039
2012-03-11 17:30:00+08:00 -1.512749
2012-03-12 17:30:00+08:00 -2.185421
2012-03-13 17:30:00+08:00 1.657845
2012-03-14 17:30:00+08:00 0.175633
Freq: D, dtype: float64
這裏是一段防爬蟲文本,請讀者忽略。
本文原創首發於 CSDN,作者 TRHX。
博客首頁:https://itrhx.blog.csdn.net/
本文鏈接:https://itrhx.blog.csdn.net/article/details/106947061
未經授權,禁止轉載!惡意轉載,後果自負!尊重原創,遠離剽竊!
【03x00】period 固定時期
【03x01】pandas.Period
固定時期(period)表示的是時間區間,比如數日、數月、數季、數年等。Period 類所表示的就是這種數據類型,其構造函數需要用到一個字符串或整數。
基本語法:
class pandas.Period(value=None, freq=None, ordinal=None,
year=None, month=None, quarter=None,
day=None, hour=None, minute=None, second=None)
官方文檔:https://pandas.pydata.org/docs/reference/api/pandas.Period.html
常用參數:
參數 | 描述 |
---|---|
value | 時間段 |
freq | 時間戳將具有的偏移量,可以是 str,日期偏移量類型,取值參見【02x02】freq 頻率部分取值 |
以下示例中,Period 對象表示的是從2020年1月1日到2020年12月31日之間的整段時間
>>> import pandas as pd
>>> pd.Period(2020, freq='A-DEC')
Period('2020', 'A-DEC')
利用加減法對其按照頻率進行位移:
>>> import pandas as pd
>>> obj = pd.Period(2020, freq='A-DEC')
>>> obj
Period('2020', 'A-DEC')
>>>
>>> obj + 5
Period('2025', 'A-DEC')
>>>
>>> obj - 5
Period('2015', 'A-DEC')
PeriodIndex 類保存了一組 Period,它可以在任何 pandas 數據結構中被用作軸索引:
>>> import pandas as pd
>>> import numpy as np
>>> rng = [pd.Period('2000-01'), pd.Period('2000-02'), pd.Period('2000-03'),
pd.Period('2000-04'), pd.Period('2000-05'), pd.Period('2000-06')]
>>> obj = pd.Series(np.random.randn(6), index=rng)
>>> obj
2000-01 0.229092
2000-02 1.515498
2000-03 -0.334401
2000-04 -0.492681
2000-05 -2.012818
2000-06 0.338804
Freq: M, dtype: float64
>>>
>>> obj.index
PeriodIndex(['2000-01', '2000-02', '2000-03', '2000-04', '2000-05', '2000-06'], dtype='period[M]', freq='M')
>>> import pandas as pd
>>> values = ['2001Q3', '2002Q2', '2003Q1']
>>> index = pd.PeriodIndex(values, freq='Q-DEC')
>>> index
PeriodIndex(['2001Q3', '2002Q2', '2003Q1'], dtype='period[Q-DEC]', freq='Q-DEC')
>>>
【03x02】period_range
pandas.period_range
方法可根據指定的頻率生成指定長度的 PeriodIndex。
基本語法:
pandas.period_range(start=None, end=None, periods=None, freq=None, name=None) → pandas.core.indexes.period.PeriodIndex
官方文檔:https://pandas.pydata.org/docs/reference/api/pandas.period_range.html
常用參數:
參數 | 描述 |
---|---|
start | 起始日期 |
end | 結束日期 |
periods | 要生成的時段數 |
freq | 時間戳將具有的偏移量,可以是 str,日期偏移量類型,取值參見【02x02】freq 頻率部分取值 |
name | 結果 PeriodIndex 對象名稱 |
簡單應用:
>>> import pandas as pd
>>> pd.period_range(start='2019-01-01', end='2020-01-01', freq='M')
PeriodIndex(['2019-01', '2019-02', '2019-03', '2019-04', '2019-05', '2019-06',
'2019-07', '2019-08', '2019-09', '2019-10', '2019-11', '2019-12',
'2020-01'],
dtype='period[M]', freq='M')
>>>
>>> pd.period_range(start=pd.Period('2017Q1', freq='Q'),
end=pd.Period('2017Q2', freq='Q'), freq='M')
PeriodIndex(['2017-03', '2017-04', '2017-05', '2017-06'], dtype='period[M]', freq='M')
【03x03】asfreq 時期頻率轉換
Period 和 PeriodIndex 對象都可以通過 asfreq 方法被轉換成別的頻率。
基本語法:PeriodIndex.asfreq(self, *args, **kwargs)
常用參數:
參數 | 描述 |
---|---|
freq | 新的頻率(偏移量),取值參見【02x02】freq 頻率部分取值 |
how | 按照開始或者結束對齊,'E' or 'END' or 'FINISH' ;'S' or 'START' or 'BEGIN' |
應用示例:
>>> import pandas as pd
>>> pidx = pd.period_range('2010-01-01', '2015-01-01', freq='A')
>>> pidx
PeriodIndex(['2010', '2011', '2012', '2013', '2014', '2015'], dtype='period[A-DEC]', freq='A-DEC')
>>>
>>> pidx.asfreq('M')
PeriodIndex(['2010-12', '2011-12', '2012-12', '2013-12', '2014-12', '2015-12'], dtype='period[M]', freq='M')
>>>
>>> pidx.asfreq('M', how='S')
PeriodIndex(['2010-01', '2011-01', '2012-01', '2013-01', '2014-01', '2015-01'], dtype='period[M]', freq='M')
【03x04】to_period 與 to_timestamp()
to_period
方法可以將 Timestamp(時間戳) 轉換爲 Period(固定時期);
to_timestamp
方法可以將 Period(固定時期)轉換爲 Timestamp(時間戳) 。
>>> import pandas as pd
>>> rng = pd.date_range('2000-01-01', periods=3, freq='M')
>>> ts = pd.Series(np.random.randn(3), index=rng)
>>> ts
2000-01-31 0.220759
2000-02-29 -0.108221
2000-03-31 0.819433
Freq: M, dtype: float64
>>>
>>> pts = ts.to_period()
>>> pts
2000-01 0.220759
2000-02 -0.108221
2000-03 0.819433
Freq: M, dtype: float64
>>>
>>> pts2 = pts.to_timestamp()
>>> pts2
2000-01-01 0.220759
2000-02-01 -0.108221
2000-03-01 0.819433
Freq: MS, dtype: float64
>>>
>>> ts.index
DatetimeIndex(['2000-01-31', '2000-02-29', '2000-03-31'], dtype='datetime64[ns]', freq='M')
>>>
>>> pts.index
PeriodIndex(['2000-01', '2000-02', '2000-03'], dtype='period[M]', freq='M')
>>>
>>> pts2.index
DatetimeIndex(['2000-01-01', '2000-02-01', '2000-03-01'], dtype='datetime64[ns]', freq='MS')
【04x00】timedelta 時間間隔
【04x01】pandas.Timedelta
Timedelta 表示持續時間,即兩個日期或時間之間的差。
Timedelta 相當於 Python 的 datetime.timedelta,在大多數情況下兩者可以互換。
基本語法:class pandas.Timedelta(value=<object object>, unit=None, **kwargs)
官方文檔:https://pandas.pydata.org/docs/reference/api/pandas.Timedelta.html
常用參數:
參數 | 描述 |
---|---|
value | 傳入的值,可以是 Timedelta,timedelta,np.timedelta64,string 或 integer 對象 |
unit | 用於設置 value 的單位,具體取值參見官方文檔 |
表示兩個 datetime 對象之間的時間差:
>>> import pandas as pd
>>> pd.to_datetime('2020-6-24') - pd.to_datetime('2016-1-1')
Timedelta('1636 days 00:00:00')
通過字符串傳遞參數:
>>> import pandas as pd
>>> pd.Timedelta('3 days 3 hours 3 minutes 30 seconds')
Timedelta('3 days 03:03:30')
通過整數傳遞參數:
>>> import pandas as pd
>>> pd.Timedelta(5,unit='h')
Timedelta('0 days 05:00:00')
獲取屬性:
>>> import pandas as pd
>>> obj = pd.Timedelta('3 days 3 hours 3 minutes 30 seconds')
>>> obj
Timedelta('3 days 03:03:30')
>>>
>>> obj.days
3
>>> obj.seconds
11010
【04x02】to_timedelta
to_timedelta 方法可以將傳入的對象轉換成 timedelta 對象。
基本語法:pandas.to_timedelta(arg, unit='ns', errors='raise')
官方文檔:https://pandas.pydata.org/docs/reference/api/pandas.to_timedelta.html
常用參數:
參數 | 描述 |
---|---|
arg | 要轉換爲 timedelta 的對象,可以是 str,timedelta,list-like 或 Series 對象 |
unit | 用於設置 arg 的單位,具體取值參見官方文檔 |
errors | 如果 arg 不滿足時間戳的形式,是否會發生異常ignore :不引發異常,返回原始輸入;raise :無效解析將引發異常(默認);coerce :無效解析將被設置爲NaT |
將單個字符串解析爲 timedelta 對象:
>>> import pandas as pd
>>> pd.to_timedelta('1 days 06:05:01.00003')
Timedelta('1 days 06:05:01.000030')
>>>
>>> pd.to_timedelta('15.5us')
Timedelta('0 days 00:00:00.000015')
將字符串列表或數組解析爲 timedelta 對象:
>>> import pandas as pd
>>> pd.to_timedelta(['1 days 06:05:01.00003', '15.5us', 'nan'])
TimedeltaIndex(['1 days 06:05:01.000030', '0 days 00:00:00.000015', NaT], dtype='timedelta64[ns]', freq=None)
指定 unit
參數:
>>> import pandas as pd
>>> pd.to_timedelta(np.arange(5), unit='s')
TimedeltaIndex(['00:00:00', '00:00:01', '00:00:02', '00:00:03', '00:00:04'], dtype='timedelta64[ns]', freq=None)
>>>
>>> pd.to_timedelta(np.arange(5), unit='d')
TimedeltaIndex(['0 days', '1 days', '2 days', '3 days', '4 days'], dtype='timedelta64[ns]', freq=None)
【04x03】timedelta_range
timedelta_range
方法可根據指定的頻率生成指定長度的 TimedeltaIndex。
基本語法:
pandas.timedelta_range(start=None, end=None, periods=None,
freq=None, name=None, closed=None) → pandas.core.indexes.timedeltas.TimedeltaIndex
官方文檔:https://pandas.pydata.org/docs/reference/api/pandas.timedelta_range.html
常用參數:
參數 | 描述 |
---|---|
start | 開始日期 |
end | 結束日期 |
periods | int 類型,要生成的時段數 |
freq | 頻率字符串,即按照某種特定的頻率來生成日期,取值參見【02x02】freq 頻率部分取值 |
name | 結果 TimedeltaIndex 的名稱 |
closed | None :默認值,同時保留開始日期和結束日期'left' :保留開始日期,不保留結束日期'right' :保留結束日期,不保留開始日期 |
應用示例:
>>> import pandas as pd
>>> pd.timedelta_range(start='1 day', periods=4)
TimedeltaIndex(['1 days', '2 days', '3 days', '4 days'], dtype='timedelta64[ns]', freq='D')
closed 參數指定保留哪個端點。默認保留兩個端點:
>>> import pandas as pd
>>> pd.timedelta_range(start='1 day', periods=4, closed='right')
TimedeltaIndex(['2 days', '3 days', '4 days'], dtype='timedelta64[ns]', freq='D')
freq 參數指定 TimedeltaIndex 的頻率。只接受固定頻率,非固定頻率如 'M'
將會報錯:
>>> import pandas as pd
>>> pd.timedelta_range(start='1 day', end='2 days', freq='6H')
TimedeltaIndex(['1 days 00:00:00', '1 days 06:00:00', '1 days 12:00:00',
'1 days 18:00:00', '2 days 00:00:00'],
dtype='timedelta64[ns]', freq='6H')
>>>
>>> pd.timedelta_range(start='1 day', end='2 days', freq='M')
Traceback (most recent call last):
...
ValueError: <MonthEnd> is a non-fixed frequency
【05x00】重採樣及頻率轉換
重採樣(resampling)指的是將時間序列從一個頻率轉換到另一個頻率的處理過程。將高頻率數據聚合到低頻率稱爲降採樣(downsampling),而將低頻率數據轉換到高頻率則稱爲升採樣(upsampling)。並不是所有的重採樣都能被劃分到這兩個大類中。例如,將 W-WED(每週三)轉換爲 W-FRI 既不是降採樣也不是升採樣。
Pandas 中提供了 resample 方法來幫助我們實現重採樣。Pandas 對象都帶有一個 resample 方法,它是各種頻率轉換工作的主力函數。
基本語法:
Series.resample(self, rule, axis=0,
closed: Union[str, NoneType] = None,
label: Union[str, NoneType] = None,
convention: str = 'start',
kind: Union[str, NoneType] = None,
loffset=None, base: int = 0,
on=None, level=None)
DataFrame.resample(self, rule, axis=0,
closed: Union[str, NoneType] = None,
label: Union[str, NoneType] = None,
convention: str = 'start',
kind: Union[str, NoneType] = None,
loffset=None, base: int = 0,
on=None, level=None)
常用參數:
參數 | 描述 |
---|---|
rule | |
axis | 重採樣的軸,默認 0 |
closed | 在重採樣中,各時間段的哪一端是閉合(即包含)的, 除 'M' 、'A' 、'Q' 、'BM' 、'BA' 、'BQ' 和 'W' 默認值爲 ‘right’ 外,其他默認值爲 'left‘ |
label | 在重採樣中,如何設置聚合值的標籤, right 或 left,默認爲 None, 例如,9:30 到 9:35 之間的這 5 分鐘會被標記爲 9:30 或 9:35 |
convention | 僅用於 PeriodIndex(固定時期),對週期進行重採樣,'start' or 's' ,'end' or 'e' |
on | 對於 DataFrame 對象,可用該參數指定重採樣後的數據的 index(行索引) 爲原數據中的某列 |
level | 對於具有層級索引(MultiIndex)的 DataFrame 對象,可以使用該參數來指定需要在哪個級別上進行重新採樣 |
將序列重採樣到三分鐘的頻率,並將每個頻率的值相加:
>>> import pandas as pd
>>> index = pd.date_range('1/1/2000', periods=9, freq='T')
>>> series = pd.Series(range(9), index=index)
>>> series
2000-01-01 00:00:00 0
2000-01-01 00:01:00 1
2000-01-01 00:02:00 2
2000-01-01 00:03:00 3
2000-01-01 00:04:00 4
2000-01-01 00:05:00 5
2000-01-01 00:06:00 6
2000-01-01 00:07:00 7
2000-01-01 00:08:00 8
Freq: T, dtype: int64
>>>
>>> series.resample('3T').sum()
2000-01-01 00:00:00 3
2000-01-01 00:03:00 12
2000-01-01 00:06:00 21
Freq: 3T, dtype: int64
設置 label='right'
,即每個索引 index 會使用靠右側(較大值)的標籤:
>>> import pandas as pd
>>> index = pd.date_range('1/1/2000', periods=9, freq='T')
>>> series = pd.Series(range(9), index=index)
>>> series
2000-01-01 00:00:00 0
2000-01-01 00:01:00 1
2000-01-01 00:02:00 2
2000-01-01 00:03:00 3
2000-01-01 00:04:00 4
2000-01-01 00:05:00 5
2000-01-01 00:06:00 6
2000-01-01 00:07:00 7
2000-01-01 00:08:00 8
Freq: T, dtype: int64
>>>
>>> series.resample('3T', label='right').sum()
2000-01-01 00:03:00 3
2000-01-01 00:06:00 12
2000-01-01 00:09:00 21
Freq: 3T, dtype: int64
設置 closed='right'
,即結果中會包含原數據中最右側(較大)的值:
>>> import pandas as pd
>>> index = pd.date_range('1/1/2000', periods=9, freq='T')
>>> series = pd.Series(range(9), index=index)
>>> series
2000-01-01 00:00:00 0
2000-01-01 00:01:00 1
2000-01-01 00:02:00 2
2000-01-01 00:03:00 3
2000-01-01 00:04:00 4
2000-01-01 00:05:00 5
2000-01-01 00:06:00 6
2000-01-01 00:07:00 7
2000-01-01 00:08:00 8
Freq: T, dtype: int64
>>>
>>> series.resample('3T', label='right', closed='right').sum()
2000-01-01 00:00:00 0
2000-01-01 00:03:00 6
2000-01-01 00:06:00 15
2000-01-01 00:09:00 15
Freq: 3T, dtype: int64
以下示例將序列重採樣到30秒的頻率,asfreq()[0:5]
用於選擇前5行數據:
>>> import pandas as pd
>>> index = pd.date_range('1/1/2000', periods=9, freq='T')
>>> series = pd.Series(range(9), index=index)
>>> series
2000-01-01 00:00:00 0
2000-01-01 00:01:00 1
2000-01-01 00:02:00 2
2000-01-01 00:03:00 3
2000-01-01 00:04:00 4
2000-01-01 00:05:00 5
2000-01-01 00:06:00 6
2000-01-01 00:07:00 7
2000-01-01 00:08:00 8
Freq: T, dtype: int64
>>>
>>> series.resample('30S').asfreq()[0:5]
2000-01-01 00:00:00 0.0
2000-01-01 00:00:30 NaN
2000-01-01 00:01:00 1.0
2000-01-01 00:01:30 NaN
2000-01-01 00:02:00 2.0
Freq: 30S, dtype: float64
使用 pad
方法向後填充缺失值(NaN):
>>> import pandas as pd
>>> index = pd.date_range('1/1/2000', periods=9, freq='T')
>>> series = pd.Series(range(9), index=index)
>>> series
2000-01-01 00:00:00 0
2000-01-01 00:01:00 1
2000-01-01 00:02:00 2
2000-01-01 00:03:00 3
2000-01-01 00:04:00 4
2000-01-01 00:05:00 5
2000-01-01 00:06:00 6
2000-01-01 00:07:00 7
2000-01-01 00:08:00 8
Freq: T, dtype: int64
>>>
>>> series.resample('30S').pad()[0:5]
2000-01-01 00:00:00 0
2000-01-01 00:00:30 0
2000-01-01 00:01:00 1
2000-01-01 00:01:30 1
2000-01-01 00:02:00 2
Freq: 30S, dtype: int64
使用 bfill
方法向前填充缺失值(NaN):
>>> import pandas as pd
>>> index = pd.date_range('1/1/2000', periods=9, freq='T')
>>> series = pd.Series(range(9), index=index)
>>> series
2000-01-01 00:00:00 0
2000-01-01 00:01:00 1
2000-01-01 00:02:00 2
2000-01-01 00:03:00 3
2000-01-01 00:04:00 4
2000-01-01 00:05:00 5
2000-01-01 00:06:00 6
2000-01-01 00:07:00 7
2000-01-01 00:08:00 8
Freq: T, dtype: int64
>>>
>>> series.resample('30S').bfill()[0:5]
2000-01-01 00:00:00 0
2000-01-01 00:00:30 1
2000-01-01 00:01:00 1
2000-01-01 00:01:30 2
2000-01-01 00:02:00 2
Freq: 30S, dtype: int64
通過 apply
方法傳遞自定義函數:
>>> import pandas as pd
>>> index = pd.date_range('1/1/2000', periods=9, freq='T')
>>> series = pd.Series(range(9), index=index)
>>> series
2000-01-01 00:00:00 0
2000-01-01 00:01:00 1
2000-01-01 00:02:00 2
2000-01-01 00:03:00 3
2000-01-01 00:04:00 4
2000-01-01 00:05:00 5
2000-01-01 00:06:00 6
2000-01-01 00:07:00 7
2000-01-01 00:08:00 8
Freq: T, dtype: int64
>>>
>>> def custom_resampler(array_like):
return np.sum(array_like) + 5
>>> series.resample('3T').apply(custom_resampler)
2000-01-01 00:00:00 8
2000-01-01 00:03:00 17
2000-01-01 00:06:00 26
Freq: 3T, dtype: int64
convention 參數的應用:
>>> import pandas as pd
>>> s = pd.Series([1, 2], index=pd.period_range('2012-01-01', freq='A', periods=2))
>>> s
2012 1
2013 2
Freq: A-DEC, dtype: int64
>>>
>>> s.resample('Q', convention='start').asfreq()
2012Q1 1.0
2012Q2 NaN
2012Q3 NaN
2012Q4 NaN
2013Q1 2.0
2013Q2 NaN
2013Q3 NaN
2013Q4 NaN
Freq: Q-DEC, dtype: float64
>>>
>>> s.resample('Q', convention='end').asfreq()
2012Q4 1.0
2013Q1 NaN
2013Q2 NaN
2013Q3 NaN
2013Q4 2.0
Freq: Q-DEC, dtype: float64
>>> import pandas as pd
>>> q = pd.Series([1, 2, 3, 4], index=pd.period_range('2018-01-01', freq='Q', periods=4))
>>> q
2018Q1 1
2018Q2 2
2018Q3 3
2018Q4 4
Freq: Q-DEC, dtype: int64
>>>
>>> q.resample('M', convention='end').asfreq()
2018-03 1.0
2018-04 NaN
2018-05 NaN
2018-06 2.0
2018-07 NaN
2018-08 NaN
2018-09 3.0
2018-10 NaN
2018-11 NaN
2018-12 4.0
Freq: M, dtype: float64
>>>
>>> q.resample('M', convention='start').asfreq()
2018-01 1.0
2018-02 NaN
2018-03 NaN
2018-04 2.0
2018-05 NaN
2018-06 NaN
2018-07 3.0
2018-08 NaN
2018-09 NaN
2018-10 4.0
2018-11 NaN
2018-12 NaN
Freq: M, dtype: float64
對於 DataFrame 對象,可以使用關鍵字 on 來指定原數據中的某列爲重採樣後數據的行索引:
>>> import pandas as pd
>>> d = dict({'price': [10, 11, 9, 13, 14, 18, 17, 19],
'volume': [50, 60, 40, 100, 50, 100, 40, 50]})
>>> df = pd.DataFrame(d)
>>> df['week_starting'] = pd.date_range('01/01/2018', periods=8, freq='W')
>>> df
price volume week_starting
0 10 50 2018-01-07
1 11 60 2018-01-14
2 9 40 2018-01-21
3 13 100 2018-01-28
4 14 50 2018-02-04
5 18 100 2018-02-11
6 17 40 2018-02-18
7 19 50 2018-02-25
>>>
>>> df.resample('M', on='week_starting').mean()
price volume
week_starting
2018-01-31 10.75 62.5
2018-02-28 17.00 60.0
對於具有層級索引(MultiIndex)的 DataFrame 對象,可以使用關鍵字 level
來指定需要在哪個級別上進行重新採樣:
>>> import pandas as pd
>>> days = pd.date_range('1/1/2000', periods=4, freq='D')
>>> d2 = dict({'price': [10, 11, 9, 13, 14, 18, 17, 19],
'volume': [50, 60, 40, 100, 50, 100, 40, 50]})
>>> df2 = pd.DataFrame(d2, index=pd.MultiIndex.from_product([days, ['morning', 'afternoon']]))
>>> df2
price volume
2000-01-01 morning 10 50
afternoon 11 60
2000-01-02 morning 9 40
afternoon 13 100
2000-01-03 morning 14 50
afternoon 18 100
2000-01-04 morning 17 40
afternoon 19 50
>>>
>>> df2.resample('D', level=0).sum()
price volume
2000-01-01 21 110
2000-01-02 22 140
2000-01-03 32 150
2000-01-04 36 90
這裏是一段防爬蟲文本,請讀者忽略。
本文原創首發於 CSDN,作者 TRHX。
博客首頁:https://itrhx.blog.csdn.net/
本文鏈接:https://itrhx.blog.csdn.net/article/details/106947061
未經授權,禁止轉載!惡意轉載,後果自負!尊重原創,遠離剽竊!