天天看點

資料分析工具:Pandas(2)

一,時間子產品:datetime
  1. datetime.date()

    日期對象(年月日)
    import datetime
    
    today = datetime.date.today()
    print(today,type(today))
    print(str(today),type(str(today)))
    # datetime.date.today 傳回今日
    # 輸出格式為 date類
    
    t = datetime.date(2016,6,1)
    print(t)
    # (年,月,日) → 直接得到當時日期
               
  2. datetime.datetime.now()

    目前時間日期對象(年,月,日,時,分,秒),自定義時間日期
    # datetime.datetime:datetime對象
    
    now = datetime.datetime.now()
    print(now,type(now))
    print(str(now),type(str(now))) 
    # .now()方法,輸出目前時間
    # 輸出格式為 datetime類
    # 可通過str()轉化為字元串
    
    t1 = datetime.datetime(2016,6,1)
    t2 = datetime.datetime(2014,1,1,12,44,33)
    print(t1,t2)
    # (年,月,日,時,分,秒),至少輸入年月日
    
    t2-t1
    # 相減得到時間差 —— timedelta
               
  3. datetime.timedelta:時間差
    today = datetime.datetime.today()  # datetime.datetime也有today()方法
    yestoday = today - datetime.timedelta(1)  # 
    print(today)
    print(yestoday)
    print(today - datetime.timedelta(7))
    # 時間差主要用作時間的加減法,相當于可被識别的時間“內插補點” 
    timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)
               
  4. parser.parse()

    :日期字元串轉換
    from dateutil.parser import parse
    date = '12-21-2017'
    t = parse(date)
    print(t,type(t))
    # 直接将str轉化成datetime.datetime
    
    print(parse('2000-1-1'),'\n',
         parse('5/1/2014'),'\n',
         parse('5/1/2014', dayfirst = True),'\n',  # 國際通用格式中,日在月之前,可以通過dayfirst來設定
         parse('22/1/2014'),'\n',
         parse('Jan 31, 1997 10:45 PM'))
    # 各種格式可以解析,但無法支援中文
               
二,,Pandas時刻資料:Timestamp

時刻資料代表時間點,是pandas的資料類型,是将值與時間點相關聯的最基本類型的時間序列資料

  1. pd.Timestamp()

    通過該方法生成pandas裡面的時刻資料(Timestamp)
    date1 = datetime.datetime(2016,12,1,12,45,30)  # 建立一個datetime.datetime
    date2 = '2017-12-21'  # 建立一個字元串
    
    t1 = pd.Timestamp(date1)
    t2 = pd.Timestamp(date2)
    # 字元串類型和datetime類型的資料轉換成Pandas的時刻資料[pd.Timestamp.timestamp(p1)-->轉換時間戳]
    print(t1, type(t1))
    print(t2,type(t1))
    print(pd.Timestamp('2017-12-21 15:00:22'), type(pd.Timestamp('2017-12-21 15:00:22')))
    # 直接生成pandas的時刻資料
    # 資料類型為 pandas的Timestamp
               
    2016-12-01 12:45:30 <class 'pandas._libs.tslibs.timestamps.Timestamp'>
    2017-12-21 00:00:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>
    2017-12-21 15:00:22 <class 'pandas._libs.tslibs.timestamps.Timestamp'>
               
  2. pd.to_datetime

    多個資料轉換成Pandas裡面的時刻資料(Timestamp)
    from datetime import datetime
    date1 = datetime(2019, 12, 1, 12, 12)
    date2 = '2018-12-01-12-12-0'
    
    t1 = pd.to_datetime(date1)
    t2 = pd.to_datetime(date2)
    print(t1, type(t1))
    print(t1, type(t2))
    # pd.to_datetime():如果是單個時間資料,轉換成pandas的時刻資料,資料類型為Timestamp
    
    list_date = ['2011/12/1', '2012-12-1', '2013,12,1']
    t3 = pd.to_datetime(list_date)
    print(t3, type(t3))
    # 多個時間資料,将會轉換為pandas的DatetimeIndex(時間序列)
               
    2019-12-01 12:12:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>
    2019-12-01 12:12:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>
    DatetimeIndex(['2011-12-01', '2012-12-01', '2013-01-01'], dtype='datetime64[ns]', freq=None) <class 'pandas.core.indexes.datetimes.DatetimeIndex'>
               

    pd.to_datetime

    補充
    # pd.to_datetime → 多個時間資料轉換時間戳索引
    from datetime import datetime
    date1 = [datetime(2015,6,1),datetime(2015,7,1),datetime(2015,8,1),datetime(2015,9,1),datetime(2015,10,1)]
    date2 = ['2017-2-1','2017-2-2','2017-2-3','2017-2-4','2017-2-5','2017-2-6']
    print(date1)
    print(date2)
    t1 = pd.to_datetime(date2)
    t2 = pd.to_datetime(date2)
    print(t1)
    print(t2)
    print('-------------------------------')
    # 多個時間資料轉換為 DatetimeIndex
    
    date3 = ['2017-2-1','2017-2-2','2017-2-3','hello world!','2017-2-5','2017-2-6']
    t3 = pd.to_datetime(date3, errors = 'ignore')
    print(t3,type(t3))
    print('--------------------------------')
    # 當一組時間序列中夾雜其他格式資料,可用errors參數傳回
    # errors = 'ignore':不可解析時傳回原始輸入,生成一般數組,裡面的正常的值是Timestamp
    
    t4 = pd.to_datetime(date3, errors = 'coerce')
    print(t4,type(t4))
    # errors = 'coerce':不可解析時傳回缺失值NaT(Not a Time),結果認為DatetimeIndex
               
    [datetime.datetime(2015, 6, 1, 0, 0), datetime.datetime(2015, 7, 1, 0, 0), datetime.datetime(2015, 8, 1, 0, 0), datetime.datetime(2015, 9, 1, 0, 0), datetime.datetime(2015, 10, 1, 0, 0)]
    ['2017-2-1', '2017-2-2', '2017-2-3', '2017-2-4', '2017-2-5', '2017-2-6']
    DatetimeIndex(['2017-02-01', '2017-02-02', '2017-02-03', '2017-02-04',
                   '2017-02-05', '2017-02-06'],
                  dtype='datetime64[ns]', freq=None)
    DatetimeIndex(['2017-02-01', '2017-02-02', '2017-02-03', '2017-02-04',
                   '2017-02-05', '2017-02-06'],
                  dtype='datetime64[ns]', freq=None)
    -------------------------------
    Index(['2017-2-1', '2017-2-2', '2017-2-3', 'hello world!', '2017-2-5',
           '2017-2-6'],
          dtype='object') <class 'pandas.core.indexes.base.Index'>
    --------------------------------
    DatetimeIndex(['2017-02-01', '2017-02-02', '2017-02-03', 'NaT', '2017-02-05',
                   '2017-02-06'],
                  dtype='datetime64[ns]', freq=None) <class 'pandas.core.indexes.datetimes.DatetimeIndex'>
               
三,Pandas時間戳索引:DatetimeIndex
  1. pd.DatetimeIndex()與TimeSeries()時間序列
    rng = pd.DatetimeIndex(['12/1/2017',
                            '12/2/2017',
                            '12/3/2017',
                            '12/4/2017',
                            '12/5/2017'])
    print(rng,type(rng))
    print(rng[0], type(rng[0]))				# DatetimeIndex類型
    print('---------------------------')
    # 直接生成時間戳索引,[]裡支援str字元串、datetime.datetime類型
    # 單個時刻資料為Timestamp,多個時刻資料為DatetimeIndex
    
    st = pd.Series(np.random.rand(5), index = rng)
    print(st,type(st))		# TimeSsries類型,以DatetimeIndex為Index的Series
    print(st.index)
    # 以DatetimeIndex為index的Series,為TimeSsries,時間序列
               
    DatetimeIndex(['2017-12-01', '2017-12-02', '2017-12-03', '2017-12-04',
                   '2017-12-05'],
                  dtype='datetime64[ns]', freq=None) <class'pandas.tseries.index.DatetimeIndex'>
    2017-12-01 00:00:00 <class 'pandas.tslib.Timestamp'>
    ---------------------------
    2017-12-01    0.837612
    2017-12-02    0.539392
    2017-12-03    0.100238
    2017-12-04    0.285519
    2017-12-05    0.939607
    dtype: float64 <class 'pandas.core.series.Series'>
    DatetimeIndex(['2017-12-01', '2017-12-02', '2017-12-03', '2017-12-04',
                   '2017-12-05'],
                  dtype='datetime64[ns]', freq=None)
               
  2. pd.date_range()

    -日期範圍:生成日期範圍
    # 2種生成方式:①start + end; ②start/end + periods
    # 預設頻率:day
    rng1 = pd.date_range('1999-12-1 12:12', '2019-12-1', normalize=True)
    rng2 = pd.date_range('19991201', periods=5)
    rng3 = pd.date_range(end='21091201 12:12:30', periods=10)
    print(rng1)
    print(rng2)
    print(rng3)
    print('---------------------------------')
    # 直接生成DatetimeIndex
    # pd.date_range(start=None, end=None, periods=None, freq='D', tz=None, normalize=False, name=None, closed=None, **kwargs)
    # start:開始時間
    # end:結束時間
    # periods:增長數(一共産生幾個時刻資料)
    # freq:頻率,預設天,pd.date_range()預設頻率為月曆日,pd.bdate_range()預設頻率為工作日
    # tz:時區
    # normalize:時間參數值正則化到午夜時間戳(這裡的12:12輸出時就直接變成0:00:00)
    
    print(pd.date_range('20170101','20170104'))
    print(pd.date_range('20170101','20170104',closed = 'right'))
    print(pd.date_range('20170101','20170104',closed = 'left'))
    # close()左右的閉合,等于right時左開又閉,等于left時左閉右開,預設None左右閉閉合
    print('---------------------------------')
    
    print(pd.bdate_range('20170101','20170107'))
    # pd.bdate_range()預設頻率為工作日
    
    print(list(pd.date_range(start = '1/1/2017', periods = 5)))
    # 直接轉化為list,元素為Timestamp
               
  3. pd.date_range()-日期範圍:頻率(1)
    # pd.date_range()-日期範圍:頻率(1)
    
    print(pd.date_range('2017/1/1','2017/1/4'))  # 預設freq = 'D':每月曆日
    print(pd.date_range('2017/1/1','2017/1/4', freq = 'B'))  # B:每工作日(=bdate)
    print(pd.date_range('2017/1/1','2017/1/2', freq = 'H'))  # H:每小時
    print(pd.date_range('2017/1/1 12:00','2017/1/1 12:10', freq = 'T'))  # T/MIN:每分
    print(pd.date_range('2017/1/1 12:00:00','2017/1/1 12:00:10', freq = 'S'))  # S:每秒
    print(pd.date_range('2017/1/1 12:00:00','2017/1/1 12:00:10', freq = 'L'))  # L:每毫秒(千分之一秒)
    print(pd.date_range('2017/1/1 12:00:00','2017/1/1 12:00:10', freq = 'U'))  # U:每微秒(百萬分之一秒)
    
    print(pd.date_range('2017/1/1','2017/2/1', freq = 'W-MON'))  
    # W-MON:從指定星期幾開始算起,每周
    # 星期幾縮寫:MON/TUE/WED/THU/FRI/SAT/SUN
    
    print(pd.date_range('2017/1/1','2017/5/1', freq = 'WOM-2MON'))  
    # WOM-2MON:每月的第幾個星期幾開始算,這裡是每月第二個星期一
               
    pd.date_range()-日期範圍:頻率(2)
    # pd.date_range()-日期範圍:頻率(2)
    
    print(pd.date_range('2017','2018', freq = 'M'))  
    print(pd.date_range('2017','2020', freq = 'Q-DEC'))  
    print(pd.date_range('2017','2020', freq = 'A-DEC')) 
    print('------')
    # M:每月最後一個月曆日
    # Q-月:指定(DEC)月為季度末,每個季度末最後一月的最後一個月曆日
    # A-月:每年指定月份的最後一個月曆日
    # 月縮寫:JAN/FEB/MAR/APR/MAY/JUN/JUL/AUG/SEP/OCT/NOV/DEC
    # 是以Q-月隻有三種情況:1-4-7-10,2-5-8-11,3-6-9-12
    
    print(pd.date_range('2017','2018', freq = 'BM'))  
    print(pd.date_range('2017','2020', freq = 'BQ-DEC'))  
    print(pd.date_range('2017','2020', freq = 'BA-DEC')) 
    print('------')
    # BM:每月最後一個工作日
    # BQ-月:指定月為季度末,每個季度末最後一月的最後一個工作日
    # BA-月:每年指定月份的最後一個工作日
    
    print(pd.date_range('2017','2018', freq = 'MS'))  
    print(pd.date_range('2017','2020', freq = 'QS-DEC'))  
    print(pd.date_range('2017','2020', freq = 'AS-DEC')) 
    print('------')
    # M:每月第一個月曆日
    # Q-月:指定月為季度末,每個季度末最後一月的第一個月曆日
    # A-月:每年指定月份的第一個月曆日
    
    print(pd.date_range('2017','2018', freq = 'BMS'))  
    print(pd.date_range('2017','2020', freq = 'BQS-DEC'))  
    print(pd.date_range('2017','2020', freq = 'BAS-DEC')) 
    # BM:每月第一個工作日
    # BQ-月:指定月為季度末,每個季度末最後一月的第一個工作日
    # BA-月:每年指定月份的第一個工作日
               
  4. pd.date_range()-日期範圍:複合頻率
    print(pd.date_range('2017/1/1','2017/2/1', freq = '7D'))  # 7天
    print(pd.date_range('2017/1/1','2017/1/2', freq = '2h30min'))  # 2小時30分鐘
    print(pd.date_range('2017','2018', freq = '2M'))  # 2月,每月最後一個月曆日
               
    DatetimeIndex(['2017-01-01', '2017-01-08', '2017-01-15', '2017-01-22',
                   '2017-01-29'],
                  dtype='datetime64[ns]', freq='7D')
    DatetimeIndex(['2017-01-01 00:00:00', '2017-01-01 02:30:00',
                   '2017-01-01 05:00:00', '2017-01-01 07:30:00',
                   '2017-01-01 10:00:00', '2017-01-01 12:30:00',
                   '2017-01-01 15:00:00', '2017-01-01 17:30:00',
                   '2017-01-01 20:00:00', '2017-01-01 22:30:00'],
                  dtype='datetime64[ns]', freq='150T')
    DatetimeIndex(['2017-01-31', '2017-03-31', '2017-05-31', '2017-07-31',
                   '2017-09-30', '2017-11-30'],
                  dtype='datetime64[ns]', freq='2M')
               
  5. asfreq:時期頻率轉換
    ts = pd.Series(np.random.rand(4),
                  index = pd.date_range('20170101','20170104'))
    print(ts)
    print(ts.asfreq('4H',method = 'ffill'))
    # 改變頻率,這裡是D改為4H
    # method:插值模式,None不插值,ffill用之前值填充,bfill用之後值填充
               
    2017-01-01    0.945391
    2017-01-02    0.656020
    2017-01-03    0.295795
    2017-01-04    0.318078
    Freq: D, dtype: float64
    2017-01-01 00:00:00    0.945391
    2017-01-01 04:00:00    0.945391
    2017-01-01 08:00:00    0.945391
    2017-01-01 12:00:00    0.945391
    2017-01-01 16:00:00    0.945391
    2017-01-01 20:00:00    0.945391
    2017-01-02 00:00:00    0.656020
    2017-01-02 04:00:00    0.656020
    2017-01-02 08:00:00    0.656020
    2017-01-02 12:00:00    0.656020
    2017-01-02 16:00:00    0.656020
    2017-01-02 20:00:00    0.656020
    2017-01-03 00:00:00    0.295795
    2017-01-03 04:00:00    0.295795
    2017-01-03 08:00:00    0.295795
    2017-01-03 12:00:00    0.295795
    2017-01-03 16:00:00    0.295795
    2017-01-03 20:00:00    0.295795
    2017-01-04 00:00:00    0.318078
    Freq: 4H, dtype: float64
               
  6. pd.date_range()-日期範圍:超前/滞後資料
    ts = pd.Series(np.random.rand(4),
                  index = pd.date_range('20170101','20170104'))
    print(ts)
    print('------')
    
    print(ts.shift(2))
    print(ts.shift(-2))
    print(ts)
    print('------')
    # 正數:數值後移(滞後);負數:數值前移(超前),不改變原來的資料
    
    per = ts/ts.shift(1) - 1
    print(per)
    print('------')
    # 計算變化百分比,這裡計算:該時間戳與上一個時間戳相比,變化百分比
    
    print(ts.shift(2, freq = 'D'))
    print(ts.shift(2, freq = 'T'))
    # 加上freq參數:對時間戳進行位移,而不是對數值進行位移
               
四,Pandas時期:Period
  1. pd.Period()

    建立時期
    p = pd.Period('2017', freq = 'M')
    print(p, type(p))
    # 生成一個以2017-01開始,月為頻率的時間構造器
    # pd.Period()參數:一個時間戳 + freq 參數 → freq 用于指明該 period 的長度,時間戳則說明該 period 在時間軸上的位置
    
    print(p + 1)
    print(p - 2)
    # 通過加減整數,将周期整體按月移動移動
    # 這裡是按照 月、年 移動
               
    2017-01 <class 'pandas._libs.tslibs.period.Period'>
    2017-02
    2016-11
               
  2. pd.period_range()

    建立時期範圍
    prng = pd.period_range('1/1/2011', '1/1/2012', freq='M')
    print(prng,type(prng))
    print(prng[0],type(prng[0]))
    # 資料格式為PeriodIndex,單個數值為Period
    
    ts = pd.Series(np.random.rand(len(prng)), index = prng)
    print(ts,type(ts))
    print(ts.index)
    # 時間序列
    
    # Period('2011', freq = 'A-DEC')可以看成多個時間期的時間段中的遊标
    # Timestamp表示一個時間戳,是一個時間截面;Period是一個時期,是一個時間段!!但兩者作為index時差別不大
               
    PeriodIndex(['2011-01', '2011-02', '2011-03', '2011-04', '2011-05', '2011-06',
                 '2011-07', '2011-08', '2011-09', '2011-10', '2011-11', '2011-12',
                 '2012-01'],
                dtype='int64', freq='M') <class 'pandas.tseries.period.PeriodIndex'>
    2011-01 <class 'pandas._period.Period'>
    2011-01    0.342571
    2011-02    0.826151
    2011-03    0.370505
    2011-04    0.137151
    2011-05    0.679976
    2011-06    0.265928
    2011-07    0.416502
    2011-08    0.874078
    2011-09    0.112801
    2011-10    0.112504
    2011-11    0.448408
    2011-12    0.851046
    2012-01    0.370605
    Freq: M, dtype: float64 <class 'pandas.core.series.Series'>
    PeriodIndex(['2011-01', '2011-02', '2011-03', '2011-04', '2011-05', '2011-06',
                 '2011-07', '2011-08', '2011-09', '2011-10', '2011-11', '2011-12',
                 '2012-01'],
                dtype='int64', freq='M')
               
  3. asfreq:頻率轉換
    p = pd.Period('2017','A-DEC')
    print(p)
    print(p.asfreq('M', how = 'start'))  # 也可寫 how = 's'
    print(p.asfreq('D', how = 'end'))  # 也可寫 how = 'e'
    # 通過.asfreq(freq, method=None, how=None)方法轉換成别的頻率
    
    prng = pd.period_range('2017','2018',freq = 'M')
    ts1 = pd.Series(np.random.rand(len(prng)), index = prng)
    ts2 = pd.Series(np.random.rand(len(prng)), index = prng.asfreq('D', how = 'start'))
    print(ts1.head(),len(ts1))
    print(ts2.head(),len(ts2))
    # asfreq也可以轉換TIMESeries的index
               
    2017
    2017-01
    2017-12-31
    2017-01    0.060797
    2017-02    0.441994
    2017-03    0.971933
    2017-04    0.000334
    2017-05    0.545191
    Freq: M, dtype: float64 13
    2017-01-01    0.447614
    2017-02-01    0.679438
    2017-03-01    0.891729
    2017-04-01    0.949993
    2017-05-01    0.942548
    Freq: D, dtype: float64 13
               
  4. 時間戳與時期之間的轉換:

    pd.to_period()、pd.to_timestamp()

    rng = pd.date_range('2017/1/1', periods = 10, freq = 'M')
    prng = pd.period_range('2017','2018', freq = 'M')
    
    ts1 = pd.Series(np.random.rand(len(rng)), index = rng)
    print(ts1.head())
    print(ts1.to_period().head())
    # 每月最後一日,轉化為每月,D和M的差別就是每個月第一天和最後一天
    
    ts2 = pd.Series(np.random.rand(len(prng)), index = prng)
    print(ts2.head())
    print(ts2.to_timestamp().head())
    # 每月,轉化為每月第一天
               
    2017-01-31    0.125288
    2017-02-28    0.497174
    2017-03-31    0.573114
    2017-04-30    0.665665
    2017-05-31    0.263561
    Freq: M, dtype: float64
    2017-01    0.125288
    2017-02    0.497174
    2017-03    0.573114
    2017-04    0.665665
    2017-05    0.263561
    Freq: M, dtype: float64
    2017-01    0.748661
    2017-02    0.095891
    2017-03    0.280341
    2017-04    0.569813
    2017-05    0.067677
    Freq: M, dtype: float64
    2017-01-01    0.748661
    2017-02-01    0.095891
    2017-03-01    0.280341
    2017-04-01    0.569813
    2017-05-01    0.067677
    Freq: MS, dtype: float64
               
五,時間序列 - 索引及切片

​ TimeSeries是Series的一個子類,是以Series索引及資料選取方面的方法基本一樣

​ 同時TimeSeries通過時間序列有更便捷的方法做索引和切片

  1. 索引
    from datetime import datetime
    
    rng = pd.date_range('2017/1','2017/3')
    ts = pd.Series(np.random.rand(len(rng)), index = rng)
    print(ts.head())
    
    print(ts[0])
    print(ts[:2])
    print('-----')
    # 基本下标位置索引
    
    print(ts['2017/1/2'])
    print(ts['20170103'])
    print(ts['1/10/2017'])
    print(ts[datetime(2017,1,20)])
    print('-----')
    # 時間序列标簽索引,支援各種時間字元串,以及datetime.datetime
    
    # 時間序列由于按照時間先後排序,故不用考慮下标順序問題
    # 索引方法同樣适用于Dataframe
               
  2. 切片
    rng = pd.date_range('2017/1','2017/3',freq = '12H')
    ts = pd.Series(np.random.rand(len(rng)), index = rng)
    
    print(ts['2017/1/5':'2017/1/10'])
    print('-----')
    # 和Series按照index索引原理一樣,也是末端包含
    
    print(ts['2017/2'].head())
    # 傳入月,直接得到一個切片
               
  3. 重複索引的時間序列
    dates = pd.DatetimeIndex(['1/1/2015','1/2/2015','1/3/2015','1/4/2015','1/1/2015','1/2/2015'])
    ts = pd.Series(np.random.rand(6), index = dates)
    print(ts)
    print(ts.is_unique,ts.index.is_unique)
    print('-----')
    # index有重複,is_unique檢查 → 判斷ts裡的values是否唯一,判斷ts裡的index是否唯一
    # 通過is_unique來做判斷
    
    print(ts['20150101'],type(ts['20150101']))
    print(ts['20150104'],type(ts['20150104']))
    print('-----')
    # index有重複的将傳回多個值
    
    print(ts.groupby(level = 0).mean())
    # 通過groupby做分組,重複的值這裡用平均值處理
    # level是以第0個為标準
               
    2015-01-01    0.300286
    2015-01-02    0.603865
    2015-01-03    0.017949
    2015-01-04    0.026621
    2015-01-01    0.791441
    2015-01-02    0.526622
    dtype: float64
    True False
    -----
    2015-01-01    0.300286
    2015-01-01    0.791441
    dtype: float64 <class 'pandas.core.series.Series'>
    2015-01-04    0.026621
    dtype: float64 <class 'pandas.core.series.Series'>
    -----
    2015-01-01    0.545863
    2015-01-02    0.565244
    2015-01-03    0.017949
    2015-01-04    0.026621
    dtype: float64
               
六,時間序列 - 重采樣

​ 重采樣:将時間序列從一個頻率轉換為另一個頻率的過程,且會有資料的結合

​ 降采樣:高頻資料 → 低頻資料,eg.以天為頻率的資料轉為以月為頻率的資料

​ 升采樣:低頻資料 → 高頻資料,eg.以年為頻率的資料轉為以月為頻率的資料

  1. 重采樣:

    .resample()

    rng = pd.date_range('20170101', periods = 12)
    ts = pd.Series(np.random.rand(12), index = rng)	# 建立以時間序列為index的Series
    print(ts)
    print('-------------')
    
    ts_re = ts.resample('5D')			# 進行一個以5天為一個頻率的時間重采樣
    ts_re = ts.resample('5D').sum
    print(ts_re)
    print(ts_re.ohlc())
    # ts.resample('5D'):得到一個重采樣建構器,頻率改為5天
    # ts.resample('5D').sum():得到一個新的聚合後的Series,聚合方式為求和
    # freq:重采樣頻率 → ts.resample('5D')
    # .sum():聚合方法
    
    print(ts.resample('5D').mean(),'→ 求平均值\n')
    print(ts.resample('5D').max(),'→ 求最大值\n')
    print(ts.resample('5D').min(),'→ 求最小值\n')
    print(ts.resample('5D').median(),'→ 求中值\n')
    print(ts.resample('5D').first(),'→ 傳回第一個值\n')
    print(ts.resample('5D').last(),'→ 傳回最後一個值\n')
    print(ts.resample('5D').ohlc(),'→ OHLC重采樣\n')
    # OHLC:金融領域的時間序列聚合方式 → open開盤、high最大值、low最小值、close收盤
               
  2. 降采樣
    rng = pd.date_range('20170101', periods = 12)
    ts = pd.Series(np.arange(1,13), index = rng)
    print(ts)
    
    print(ts.resample('5D').sum(),'→ 預設\n')
    print(ts.resample('5D', closed = 'left').sum(),'→ left\n')
    print(ts.resample('5D', closed = 'right').sum(),'→ right\n')
    print('-----')
    # closed:各時間段哪一端是閉合(即包含)的,預設 左閉右閉
    # 詳解:這裡values為0-11,按照5D重采樣 → [1,2,3,4,5],[6,7,8,9,10],[11,12]
    # left指定間隔左邊為結束 → [1,2,3,4,5],[6,7,8,9,10],[11,12]
    # right指定間隔右邊為結束 → [1],[2,3,4,5,6],[7,8,9,10,11],[12]
    
    print(ts.resample('5D', label = 'left').sum(),'→ leftlabel\n')
    print(ts.resample('5D', label = 'right').sum(),'→ rightlabel\n')
    # label:聚合值的index,預設為取采集的樣本的最左邊index顯示
    # 值采樣認為預設(這裡closed預設)
               
  3. 升采樣
    rng = pd.date_range('2017/1/1 0:0:0', periods = 5, freq = 'H')
    ts = pd.DataFrame(np.arange(15).reshape(5,3),
                      index = rng,
                      columns = ['a','b','c'])
    print(ts)
    
    print(ts.resample('15T').asfreq())
    print(ts.resample('15T').ffill())
    print(ts.resample('15T').bfill())
    # 低頻轉高頻,主要是如何插值
    # .asfreq():不做填充,傳回Nan
    # .ffill():向上填充
    # .bfill():向下填充
               
  4. 時期重采樣 - Period
    prng = pd.period_range('2016','2017',freq = 'M')
    ts = pd.Series(np.arange(len(prng)), index = prng)
    print(ts)
    
    print(ts.resample('3M').sum())  # 降采樣
    print(ts.resample('15D').ffill())  # 升采樣
               

繼續閱讀