当前位置:   article > 正文

Pandas数据分析22——pandas时间序列_pandas astype datetime

pandas astype datetime

 参考书目:《深入浅出Pandas:利用Python进行数据处理与分析》


pandas的索引可以用时间来替代,然后基于时间序列数据会有很多用法,了解一下。

时间对象有:

还是先导入包:

  1. import numpy as np
  2. import pandas as pd
  3. import datetime

时序索引

#创建时间索引

pd里面的对象,或者字符串,np对象,和Python的datetime对象都可以直接创建时间索引。

pd.to_datetime(['11/1/2020',np.datetime64('2020-11-02'),datetime.datetime(2020,11,3)])

 date_range创建一组时间,即时间序列

  1. #默认频率为天
  2. pd.date_range('2020-01-01',periods=10)
  3. pd.date_range('2020-01-01','2020-01-10') #同上
  4. pd.date_range(end='2020-01-10',periods=10)#同上
  5. pd.date_range('2022-01-01', periods=3, freq='H')#频率为小时

 #跳过星期六天

pd.bdate_range('2020-11-1',periods=10)

 #通常时间序列数据作为 Series 或 DataFrame 的索引,以方便对时间数据进行操作。

  1. # 指定开始时间和频率,周期数
  2. pd.Series(range(3), index=pd.date_range('2000', freq='D', periods=3))


索引访问

和其他种类数据一样,时间序列也是可以用[],.loc[]方法进行切片选取数据的。

生成案例数据

  1. rng = pd.date_range('1/1/2021', '12/1/2021', freq='BM')
  2. ts = pd.Series(np.random.randn(len(rng)), index=rng)
  3. ts

#时间索引切片 

  1. #DatetimeIndex 作为时间索引,同样也支持数据切片:
  2. ts[2:4]

ts[0:4].index  #ts[::2].index

#还支持传入时间字符和各种时间对象 

  1. ts['2021'] #z只筛选2021年的
  2. ts['1/29/2021']#查询这一天的值
  3. ts['2021-1-29']#同上
  4. ts['20210129'] #同上
  5. ts[datetime.datetime(2021, 9, 30):]
  6. ts[pd.Timestamp(2021,9,30)]
  7. ts[pd.Timestamp('2021-9-30')]
  8. ts[np.datetime64('2021-9-30')]

 #也可以使用部分字符查询一定范围的数据:

  1. ts['2021'] # 查询整个2021年的
  2. ts['2021-6'] # 查询 2021年6月的
  3. ts['2021-6':'2021-10'] # 6月到10月的
  4. dft['2013-1':'2013-2-28 00:00:00'] # 精确时间
  5. dft['2013-1-15':'2013-1-15 12:30:00']
  6. dft2.loc['2013-01-05']

类型转化


#由于时间格式样式比较多,很多情况下 Padnas 并不能自动识别为时间类型,所以我们在处理前的数据清洗过程中,需要专门对数据进行时间类型转换。
#astype 是最简单的时间转换方法,它只能针对相对标准的时间格式,如:

  1. s = pd.Series(['2016-01-31', '2016-02-29', '2016-03-31'])
  2. s.astype('datetime64[ns]')

#修改频率

s.astype('datetime64[D]')

pd.to_datetime(s)


#转为不同时间粒度

#在上文中,我们转换时间时使用的是 ns (纳秒),最大程度地保留了最细的时间颗粒的供我们未来使用,但有时间我们不需要这么精确的细小粒度,如何操作呢?这就需要在 datetime64 后的括号里指定我们想要的粒度,如:

  1. # 一个时间文本序列
  2. s = pd.Series(['2016-01-31 10:18:04', '2016-02-29 12:18:09'])
  3. s
  4. '''
  5. 0 2016-01-31 10:18:04
  6. 1 2016-02-29 12:18:09
  7. dtype: object
  8. '''
  9. # 纳秒级
  10. s.astype('datetime64[ns]')
  11. '''
  12. 0 2016-01-31 10:18:04
  13. 1 2016-02-29 12:18:09
  14. dtype: datetime64[ns]
  15. '''
  16. # 日级
  17. s.astype('datetime64[D]')
  18. '''
  19. 0 2016-01-31
  20. 1 2016-02-29
  21. dtype: datetime64[ns]
  22. '''
  23. # 小时级
  24. s.astype('datetime64[h]')
  25. '''
  26. 0 2016-01-31 10:00:00
  27. 1 2016-02-29 12:00:00
  28. dtype: datetime64[ns]
  29. '''
  30. # 秒级
  31. s.astype('datetime64[s]')
  32. '''
  33. 0 2016-01-31 10:18:04
  34. 1 2016-02-29 12:18:09
  35. dtype: datetime64[ns]
  36. '''
  37. # 月级,当月第一天
  38. s.astype('datetime64[M]')
  39. '''
  40. 0 2016-01-01
  41. 1 2016-02-01
  42. dtype: datetime64[ns]
  43. '''
  44. # 年级,当年第一天
  45. s.astype('datetime64[Y]')
  46. '''
  47. 0 2016-01-01
  48. 1 2016-01-01
  49. dtype: datetime64[ns]
  50. '''
  51. # 周级,当周周四(原因如下)
  52. s.astype('datetime64[W]')
  53. '''
  54. 0 2016-01-28
  55. 1 2016-02-25
  56. dtype: datetime64[ns]
  57. '''

'datetime64[W]' 的结果为周四是因为这只是四舍五入,是经过设计的。括号里还可以为 2W、7D等开工,如 7D 的意思是“自纪元(1970-01-01T00:00Z )以来7D的倍数”,就像 D 的意思是“自纪元以来一天的倍数”,7D 和 W 是同义词。

我们可以看到,除了周、月、年等,其他粒度仍然以纳秒存储,不过精确度都会损失。这个规划在下边我们介绍的 pd.to_datetime() 中也适用。


转为时间 pd.to_datetime

#Pandas 提供的 pd.to_datetime() 是识别转换时间的主要工具。接下来看一些例子。

#从 DataFrame 的多个列中组合一个日期时间。 键可以是常见的缩写,例如['year','month','day','minute','second','ms','us','ns']): 必须: year, month, day 可选: hour, minute, second, millisecond, microsecond, nanosecond

  1. df = pd.DataFrame({'year': [2015, 2016],
  2. 'month': [2, 3],
  3. 'day': [4, 5]})
  4. df

  1. pd.to_datetime(df)
  2. pd.to_datetime(df[['year', 'month', 'day']]) # 同上

 #对Series智能解析时间:

pd.to_datetime(pd.Series(['Jul 31, 2009', '2010-01-10', None]))

 #列表也可以智能

  1. pd.to_datetime(['2005/11/23', '2010.12.31'])
  2. # DatetimeIndex(['2005-11-23', '2010-12-31'], dtype='datetime64[ns]', freq=None)
  3. pd.to_datetime(['04-01-2012 10:00'], dayfirst=True) # 日期在前
  4. # DatetimeIndex(['2012-01-04 10:00:00'], dtype='datetime64[ns]', freq=None)
  1. #pd.DatetimeIndex 也可以转换:
  2. pd.DatetimeIndex(['2018-01-01', '2018-01-03', '2018-01-05'])
  3. # DatetimeIndex(['2018-01-01', '2018-01-03', '2018-01-05'], dtype='datetime64[ns]', freq=None)
  4. pd.DatetimeIndex(['20180101', '20180103', '20180105'], freq='infer') #自动推断频率
  5. # DatetimeIndex(['2018-01-01', '2018-01-03', '2018-01-05'], dtype='datetime64[ns

 #可以使用 pd.Timestamp() 进行转换单个时间点

  1. pd.to_datetime('2010/11/12')
  2. # Timestamp('2010-11-12 00:00:00')
  3. pd.Timestamp('2020/11/12')
  4. # Timestamp('2020-11-12 00:00:00')

按格式转换

#不规则格式转化时间

pd.to_datetime('2020_11_12',format='%Y_%m_%d',errors='ignore')

 

pd.to_datetime('20200101', format='%Y%m%d', errors='ignore')

# 可以让系统自己推断时间格式

pd.to_datetime('20200101', infer_datetime_format=True, errors='ignore')

  1. # coerce 将不会忽略错误,返回空值
  2. pd.to_datetime('13000101', format='%Y%m%d', errors='coerce')

# 有时间需要字段转为字符,再转为时间

  1. pd.to_datetime(df.d.astype(str), format='%m/%d/%Y')
  2. # 其他
  3. pd.to_datetime('2010/11/12', format='%Y/%m/%d')
  4. # Timestamp('2010-11-12 00:00:00')
  5. pd.to_datetime('12-11-2010 00:00', format='%d-%m-%Y %H:%M')
  6. # Timestamp('2010-11-12 00:00:00')
  7. #对时间戳进行转换,需要给出时间单位,一般为秒:
  8. pd.to_datetime(1490195805, unit='s')
  9. # Timestamp('2017-03-22 15:16:45')
  10. pd.to_datetime(1490195805433502912, unit='ns')
  11. # Timestamp('2017-03-22 15:16:45.433502912')
  12. #对周期数据(数字列表)进行转换:
  13. pd.to_datetime([1, 2, 3], unit='D',origin=pd.Timestamp('1960-01-01'))
  14. # DatetimeIndex(['1960-01-02', '1960-01-03', '1960-01-04'], dtype='datetime64[ns]', fre

 时间维度转化

 有时候不想要时间后面的小时,可以这样转化

pd.date_range('2022-1-1 00:10:00','2022-8-6 00:10:00').floor(freq='D') #忽略小时

 上面的时间粒度方法也可以转化

  1. s=pd.Series(pd.date_range('2022-1-1','2022-8-6')).astype('datetime64[M]')
  2. pd.to_datetime(s.astype(str),format='%Y-%m') #实在不行字符串切。。

 如果不想要20222-08-01后面的-01,可以用字符串去切,然后再变成时间。。

  1. def time_t(time):
  2. t=time.split('-')
  3. return t[0]+'-'+t[1]
  4. pd.to_datetime(s.astype('str').apply(time_t))

 


 

.dt 时间访问器

#对于时间序列数据,可以使用 s.dt.xxx 的形式来访问它们的属性和调用它们的方法

  1. s = pd.Series(pd.date_range('2020-01-01', periods=3, freq='d'))
  2. s.dt.date
  3. s.dt.time
  4. s.dt.timetz
  5. s.dt.year
  6. s.dt.month
  7. s.dt.day
  8. s.dt.hour
  9. s.dt.minute
  10. s.dt.second
  11. s.dt.microsecond
  12. s.dt.nanosecond
  13. #周月年相关
  14. s.dt.week
  15. s.dt.weekofyear
  16. s.dt.dayofweek
  17. s.dt.weekday
  18. s.dt.dayofyear #一年中第几天
  19. s.dt.quarter #季度数
  20. s.dt.is_month_start #是否月第一天
  21. s.dt.is_month_end #是否最后一天
  22. s.dt.is_quarter_start#是否季度第一天
  23. s.dt.is_quarter_end #是否季度最后一天
  24. s.dt.is_year_start #是否年第一天
  25. s.dt.is_year_end #是否年最后一天
  26. s.dt.is_leap_year #是否闰年
  27. s.dt.daysinmonth #当月多少天
  28. s.dt.days_in_month #同上
  29. s.dt.tz #时区
  30. s.dt.freq #频率
  31. #转化方法
  32. s.dt.to_period
  33. s.dt.to_pydatetime
  34. s.dt.tz_localize
  35. s.dt.tz_convert
  36. s.dt.normalize
  37. s.dt.strftime
  38. s.dt.round(fred='D')#类似四舍五入
  39. s.dt.floor(fred='D')#向下舍入为天
  40. s.dt.ceil(fred='D') #向上舍入为天
  41. s.dt.month_name #月份名称
  42. s.dt.day_name #星期几名称
  43. s.dt.qyear
  44. s.dt.start_time #开始时间
  45. s.dt.end_time #结束时间
  46. s.dt.days #天数
  47. s.dt.seconds #秒
  48. s.dt.microseconds #毫秒
  49. s.dt.nanoseconds #纳秒
  50. s.dt.components #时间成分
  51. s.dt.to_pytimedelta #转为py时间
  52. s.dt.total_seconds #总秒数

移动 Shifting

 #可能需要将时间序列中的值在时间上前后移动或滞后。 shift() 方法也可以在时序对象上使用。

  1. index = pd.date_range('2020-06-01', '2020-06-03')
  2. ts = pd.Series(range(len(rng)), index=index)
  3. ts

ts.shift(-1)

ts.shift(-1,freq='B')


频率转换 asfreq()

有时候需要将低频率数据改为高频数据

  1. #更改频率的主要功能是 asfreq() 方法。
  2. dr = pd.date_range('1/1/2022', periods=3, freq=3 * pd.offsets.BDay())
  3. ts = pd.Series(np.random.randn(3), index=dr)
  4. ts

日期频率

ts.asfreq(pd.offsets.BDay())

 半天频率

ts.asfreq(pd.offsets.Hour(12))

 #asfreq 提供了更多便利,因此您可以为频率转换后可能出现的任何间隙指定插值方法。

ts.asfreq(pd.offsets.BDay(), method='pad')  #扩展填充

  1. # 对空值进行固定值填充
  2. ts.asfreq(freq='12h', fill_value=9.0)


扩充日期,填充

#以使用几个选项之一({None, ‘backfill’/’bfill’, ‘pad’/’ffill’, ‘nearest’})来填写缺失值。
#例如,要反向传播最后一个有效值以填充NaN值,请将 bfill 作为参数传递给method关键字。

ts.reindex(pd.date_range('2022-1-1', periods=15, freq='D'), method='ffill')

 可以看到有效的将三个数据扩充到更多的额时间天上,并且值填充保持不变。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/234376
推荐阅读
相关标签
  

闽ICP备14008679号