• Pandas日期数据处理:如何按日期筛选、显示及统计数据


    对于我们宽客相对重要一些,在本地实现回测和交易的宽客,需要自己清洗数据。

    而证券行情数据是时间序列数据,和时间索引又分不开,下面这篇文章,帮助我们更好的使用pandas处理和日期时间相关的数据。

    该文引自:http://www.mamicode.com/info-detail-1822406.html 

    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    前言

    pandas有着强大的日期数据处理功能,本期我们来了解下pandas处理日期数据的一些基本功能,主要包括以下三个方面:

    • 按日期筛选数据
    • 按日期显示数据
    • 按日期统计数据

    运行环境为 windows系统,64位,python3.5。

    1 读取并整理数据

    • 首先引入pandas库
      import pandas as pd
      
    • 从csv文件中读取数据
    df = pd.read_csv(‘date.csv‘, header=None)
    print(df.head(2))
    
                0  1
    0  2013-10-24  3
    1  2013-10-25  4
    
    • 整理数据
    df.columns = [‘date‘,‘number‘]
    df[‘date‘] = pd.to_datetime(df[‘date‘]) #将数据类型转换为日期类型
    df = df.set_index(‘date‘) # 将date设置为index
    print(df.head(2))
    print(df.tail(2))
    print(df.shape)
    
                number
    date              
    2013-10-24       3
    2013-10-25       4
                number
    date              
    2017-02-14       6
    2017-02-22       6
    (425, 1)
    
    • df的行数一共是425行。

    查看Dataframe的数据类型

    print(type(df))
    print(df.index)
    print(type(df.index))
    
    <class ‘pandas.core.frame.DataFrame‘>
    DatetimeIndex([‘2013-10-24‘, ‘2013-10-25‘, ‘2013-10-29‘, ‘2013-10-30‘,
                   ‘2013-11-04‘, ‘2013-11-06‘, ‘2013-11-08‘, ‘2013-11-12‘,
                   ‘2013-11-14‘, ‘2013-11-25‘,
                   ...
                   ‘2017-01-03‘, ‘2017-01-07‘, ‘2017-01-14‘, ‘2017-01-17‘,
                   ‘2017-01-23‘, ‘2017-01-25‘, ‘2017-01-26‘, ‘2017-02-07‘,
                   ‘2017-02-14‘, ‘2017-02-22‘],
                  dtype=‘datetime64[ns]‘, name=‘date‘, length=425, freq=None)
    <class ‘pandas.tseries.index.DatetimeIndex‘>
    

    构造Series类型数据

    s = pd.Series(df[‘number‘], index=df.index)
    print(type(s))
    s.head(2)
    
    <class ‘pandas.core.series.Series‘>
    
    date
    2013-10-24    3
    2013-10-25    4
    Name: number, dtype: int64
    

    2 按日期筛选数据

    按年度获取数据

    print(‘---------获取2013年的数据-----------‘)
    print(df[‘2013‘].head(2)) # 获取2013年的数据
    print(df[‘2013‘].tail(2)) # 获取2013年的数据
    
    ---------获取2013年的数据-----------
                number
    date              
    2013-10-24       3
    2013-10-25       4
                number
    date              
    2013-12-27       2
    2013-12-30       2
    

    获取2016至2017年的数据

    print(‘---------获取2016至2017年的数据-----------‘)
    print(df[‘2016‘:‘2017‘].head(2))  #获取2016至2017年的数据
    print(df[‘2016‘:‘2017‘].tail(2))  #获取2016至2017年的数据
    
    ---------获取2016至2017年的数据-----------
                number
    date              
    2016-01-04       4
    2016-01-07       6
                number
    date              
    2017-02-14       6
    2017-02-22       6
    

    获取某月的数据

    print(‘---------获取某月的数据-----------‘)
    print(df[‘2013-11‘]) # 获取某月的数据
    
    ---------获取某月的数据-----------
                number
    date              
    2013-11-04       1
    2013-11-06       3
    2013-11-08       1
    2013-11-12       5
    2013-11-14       2
    2013-11-25       1
    2013-11-29       1
    

    获取具体某天的数据

    • 请注意dataframe类型的数据,获取具体某天的数据时,跟series是有些差异的,详细情况如下述代码所示:
    # 按日期筛选数据
    print(‘---------获取具体某天的数据-----------‘)
    # 获取具体某天的数据
    print(s[‘2013-11-06‘])
    
    # 获取具体某天的数据,用datafrme直接选取某天时会报错,而series的数据就没有问题
    # print(df[‘2013-11-06‘])
    
    #可以考虑用区间来获取某天的数据
    print(df[‘2013-11-06‘:‘2013-11-06‘])
    
    ---------获取具体某天的数据-----------
    3
                number
    date              
    2013-11-06       3
    
    • dataframe的truncate函数可以获取某个时期之前或之后的数据,或者某个时间区间的数据
    • 但一般建议直接用切片(slice),这样更为直观,方便
    # dataframe的truncate函数可以获取某个时期之前或之后的数据,或者某个时间区间的数据
    # 但一般建议直接用切片(slice),这样更为直观,方便
    print(‘---------获取某个时期之前或之后的数据-----------‘)
    print(‘--------after------------‘)
    print(df.truncate(after = ‘2013-11‘))
    print(‘--------before------------‘)
    print(df.truncate(before=‘2017-02‘))
    
    ---------获取某个时期之前或之后的数据-----------
    --------after------------
                number
    date              
    2013-10-24       3
    2013-10-25       4
    2013-10-29       2
    2013-10-30       1
    --------before------------
                number
    date              
    2017-02-07       8
    2017-02-14       6
    2017-02-22       6
    

    3 按日期显示数据

    3.1 to_period()方法

    • 请注意df.index的数据类型是DatetimeIndex;
    • df_peirod的数据类型是PeriodIndex

    按月显示,但不统计

    df_period = df.to_period(‘M‘) #按月显示,但不统计
    print(type(df_period))
    
    print(type(df_period.index))
    # 请注意df.index的数据类型是DatetimeIndex;
    # df_peirod的数据类型是PeriodIndex
    
    print(df_period.head())
    
    <class ‘pandas.core.frame.DataFrame‘>
    <class ‘pandas.tseries.period.PeriodIndex‘>
             number
    date           
    2013-10       3
    2013-10       4
    2013-10       2
    2013-10       1
    2013-11       1
    

    按季度显示,但不统计

    print(df.to_period(‘Q‘).head()) #按季度显示,但不统计
    
            number
    date          
    2013Q4       3
    2013Q4       4
    2013Q4       2
    2013Q4       1
    2013Q4       1
    

    按年度显示,但不统计

    print(df.to_period(‘A‘).head()) #按年度显示,但不统计
    
          number
    date        
    2013       3
    2013       4
    2013       2
    2013       1
    2013       1
    

    3.2 asfreq()方法

    按年度频率显示

    df_period.index.asfreq(‘A‘) # ‘A‘默认是‘A-DEC‘,其他如‘A-JAN‘
    
    PeriodIndex([‘2013‘, ‘2013‘, ‘2013‘, ‘2013‘, ‘2013‘, ‘2013‘, ‘2013‘, ‘2013‘,
                 ‘2013‘, ‘2013‘,
                 ...
                 ‘2017‘, ‘2017‘, ‘2017‘, ‘2017‘, ‘2017‘, ‘2017‘, ‘2017‘, ‘2017‘,
                 ‘2017‘, ‘2017‘],
                dtype=‘period[A-DEC]‘, name=‘date‘, length=425, freq=‘A-DEC‘)
    
    df_period.index.asfreq(‘A-JAN‘) # ‘A‘默认是‘A-DEC‘,其他如‘A-JAN‘
    
    PeriodIndex([‘2014‘, ‘2014‘, ‘2014‘, ‘2014‘, ‘2014‘, ‘2014‘, ‘2014‘, ‘2014‘,
                 ‘2014‘, ‘2014‘,
                 ...
                 ‘2017‘, ‘2017‘, ‘2017‘, ‘2017‘, ‘2017‘, ‘2017‘, ‘2017‘, ‘2018‘,
                 ‘2018‘, ‘2018‘],
                dtype=‘period[A-JAN]‘, name=‘date‘, length=425, freq=‘A-JAN‘)
    
    • 按年度频率在不同情形下的显示,可参考下图所示: 技术分享

    按季度频率显示

    df_period.index.asfreq(‘Q‘) # ‘Q‘默认是‘Q-DEC‘,其他如“Q-SEP”,“Q-FEB”
    
    PeriodIndex([‘2013Q4‘, ‘2013Q4‘, ‘2013Q4‘, ‘2013Q4‘, ‘2013Q4‘, ‘2013Q4‘,
                 ‘2013Q4‘, ‘2013Q4‘, ‘2013Q4‘, ‘2013Q4‘,
                 ...
                 ‘2017Q1‘, ‘2017Q1‘, ‘2017Q1‘, ‘2017Q1‘, ‘2017Q1‘, ‘2017Q1‘,
                 ‘2017Q1‘, ‘2017Q1‘, ‘2017Q1‘, ‘2017Q1‘],
                dtype=‘period[Q-DEC]‘, name=‘date‘, length=425, freq=‘Q-DEC‘)
    
    df_period.index.asfreq(‘Q-SEP‘) # 可以显示不同的季度财年,“Q-SEP”,“Q-FEB”
    # df_period.index = df_period.index.asfreq(‘Q-DEC‘) # 可以显示不同的季度财年,“Q-SEP”,“Q-FEB”
    # print(df_period.head())
    
    PeriodIndex([‘2014Q1‘, ‘2014Q1‘, ‘2014Q1‘, ‘2014Q1‘, ‘2014Q1‘, ‘2014Q1‘,
                 ‘2014Q1‘, ‘2014Q1‘, ‘2014Q1‘, ‘2014Q1‘,
                 ...
                 ‘2017Q2‘, ‘2017Q2‘, ‘2017Q2‘, ‘2017Q2‘, ‘2017Q2‘, ‘2017Q2‘,
                 ‘2017Q2‘, ‘2017Q2‘, ‘2017Q2‘, ‘2017Q2‘],
                dtype=‘period[Q-SEP]‘, name=‘date‘, length=425, freq=‘Q-SEP‘)
    
    • 按季度频率在不同情形下的显示,可参考下图所示: 技术分享

    按月度频率显示

    df_period.index.asfreq(‘M‘) # 按月份显示
    
    PeriodIndex([‘2013-10‘, ‘2013-10‘, ‘2013-10‘, ‘2013-10‘, ‘2013-11‘, ‘2013-11‘,
                 ‘2013-11‘, ‘2013-11‘, ‘2013-11‘, ‘2013-11‘,
                 ...
                 ‘2017-01‘, ‘2017-01‘, ‘2017-01‘, ‘2017-01‘, ‘2017-01‘, ‘2017-01‘,
                 ‘2017-01‘, ‘2017-02‘, ‘2017-02‘, ‘2017-02‘],
                dtype=‘period[M]‘, name=‘date‘, length=425, freq=‘M‘)
    

    按工作日显示

    • method 1
    df_period.index.asfreq(‘B‘, how=‘start‘) # 按工作日期显示
    
    PeriodIndex([‘2013-10-01‘, ‘2013-10-01‘, ‘2013-10-01‘, ‘2013-10-01‘,
                 ‘2013-11-01‘, ‘2013-11-01‘, ‘2013-11-01‘, ‘2013-11-01‘,
                 ‘2013-11-01‘, ‘2013-11-01‘,
                 ...
                 ‘2017-01-02‘, ‘2017-01-02‘, ‘2017-01-02‘, ‘2017-01-02‘,
                 ‘2017-01-02‘, ‘2017-01-02‘, ‘2017-01-02‘, ‘2017-02-01‘,
                 ‘2017-02-01‘, ‘2017-02-01‘],
                dtype=‘period[B]‘, name=‘date‘, length=425, freq=‘B‘)
    
    • method 2
    df_period.index.asfreq(‘B‘, how=‘end‘) # 按工作日期显示
    
    PeriodIndex([‘2013-10-31‘, ‘2013-10-31‘, ‘2013-10-31‘, ‘2013-10-31‘,
                 ‘2013-11-29‘, ‘2013-11-29‘, ‘2013-11-29‘, ‘2013-11-29‘,
                 ‘2013-11-29‘, ‘2013-11-29‘,
                 ...
                 ‘2017-01-31‘, ‘2017-01-31‘, ‘2017-01-31‘, ‘2017-01-31‘,
                 ‘2017-01-31‘, ‘2017-01-31‘, ‘2017-01-31‘, ‘2017-02-28‘,
                 ‘2017-02-28‘, ‘2017-02-28‘],
                dtype=‘period[B]‘, name=‘date‘, length=425, freq=‘B‘)
    

    4 按日期统计数据

    4.1按日期统计数据

    按周统计数据

    print(df.resample(‘w‘).sum().head())
    # “w”,week
    
                number
    date              
    2013-10-27     7.0
    2013-11-03     3.0
    2013-11-10     5.0
    2013-11-17     7.0
    2013-11-24     NaN
    

    按月统计数据

    print(df.resample(‘M‘).sum().head())
    # "MS"是每个月第一天为开始日期, "M"是每个月最后一天
    
                number
    date              
    2013-10-31      10
    2013-11-30      14
    2013-12-31      27
    2014-01-31      16
    2014-02-28       4
    

    按季度统计数据

    print(df.resample(‘Q‘).sum().head())
    # "QS"是每个季度第一天为开始日期, "Q"是每个季度最后一天
    
                number
    date              
    2013-12-31      51
    2014-03-31      73
    2014-06-30      96
    2014-09-30     136
    2014-12-31     148
    

    按年统计数据

    
    print(df.resample(‘AS‘).sum())
    # "AS"是每年第一天为开始日期, "A是每年最后一天
    
                number
    date              
    2013-01-01      51
    2014-01-01     453
    2015-01-01     743
    2016-01-01    1552
    2017-01-01      92
    
    • 关于日期的类型,按参考下图所示来选择合适的分期频率: 技术分享

    4.2 按日期统计后,按年或季度或月份显示

    按年统计并显示

    print(df.resample(‘AS‘).sum().to_period(‘A‘))
    # 按年统计并显示
    
          number
    date        
    2013      51
    2014     453
    2015     743
    2016    1552
    2017      92
    

    按季度统计并显示

    print(df.resample(‘Q‘).sum().to_period(‘Q‘).head())
    # 按季度统计并显示
    
            number
    date          
    2013Q4      51
    2014Q1      73
    2014Q2      96
    2014Q3     136
    2014Q4     148
    

    按月度统计并显示

    print(df.resample(‘M‘).sum().to_period(‘M‘).head())
    # 按月度统计并显示
    
             number
    date           
    2013-10      10
    2013-11      14
    2013-12      27
    2014-01      16
    2014-02       4
    

     

  • 相关阅读:
    用mysql++读写二进制
    mysql++的release版本当机的问题
    mongo的安装
    什么是新装用电和增加用电
    填写用电报装申请表
    湖南省居民生活阶梯电价政策问答
    什么是阶梯电价
    用case when 动态给sql 添加 查询条件
    js 原型 继承
    可编辑的表格
  • 原文地址:https://www.cnblogs.com/GavinSimons/p/8470752.html
Copyright © 2020-2023  润新知