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

Posted lemonbit

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Pandas日期数据处理:如何按日期筛选显示及统计数据相关的知识,希望对你有一定的参考价值。

 

前言

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

更多精彩内容请关注微信公众号:

“Python数据之道”

 

以上是关于Pandas日期数据处理:如何按日期筛选显示及统计数据的主要内容,如果未能解决你的问题,请参考以下文章

数据分析处理库Pandas——时间

Pandas分组统计与时间序列

如何在Java中对MongoDB按日期进行查询统计

sql中如何把具体日期转化为按月排序?

pandas通过DatetimeProperties对象获取日期对象是否是所在年份的最后一天(is year end)筛选dataframe数据中日期对象是所在年份最后一天的数据行

pandas通过DatetimeProperties对象获取日期对象是否是所在月份的最后一天(is month end)筛选dataframe数据中日期对象是所在月份最后一天的数据行