pandas基础(时间日期)

本文介绍了Python标准库中的时间日期处理,重点关注Pandas中时间序列的使用,包括Timestamp、date_range、Period、时间频率转换、时间重采样及其在金融数据中的应用。通过实例展示了如何进行日期范围生成、时间戳与日期的转换、时期算术运算以及不同频率的重采样方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

时间日期

  • 时间戳 tiimestamp:固定的时刻 -> pd.Timestamp
  • 固定时期 period:比如2016年3月份,再如2015年销售额 -> pd.Period 时间间隔
  • interval:由起始时间和结束时间来表示,固定时期是一个特殊的时间间隔

Python标准库中对时间日期的处理

datetime

python 标准库里提供了时间日期的处理,这个是时间日期的基础。

from datetime import datetime
from datetime import timedelta
now = datetime.now()
now

运行结果为:
datetime.datetime(2016, 4, 28, 14, 49, 51, 307000)
now.year, now.month, now.day

运行结果为:
(2016, 4, 28)

时间差

date1 = datetime(2016, 3, 20)
date2 = datetime(2016, 3, 16)
delta = date1 - date2
delta

运行结果为:
datetime.timedelta(4)
delta.days

运行结果为:
4
delta.total_seconds()

运行结果为:
345600.0
date2 + delta

运行结果为:
datetime.datetime(2016, 3, 20, 0, 0)

date2 + timedelta(4.5)

运行结果为:
datetime.datetime(2016, 3, 20, 12, 0)

字符串和 datetime 转换

date = datetime(2016, 3, 20, 8, 30)
date

运行结果为:
datetime.datetime(2016, 3, 20, 8, 30)
str(date)

运行结果为:
'2016-03-20 08:30:00'
# strftime() 函数接收以时间元组,并返回以可读字符串表示的当地时间,格式由参数format决定。
date.strftime('%Y-%m-%d %H:%M:%S')

运行结果为:
'2016-03-20 08:30:00'

strftime()函数用法

# strptime() 函数根据指定的格式把一个时间字符串解析为时间元组。
datetime.strptime('2016-03-20 09:30', '%Y-%m-%d %H:%M')

运行结果为:
datetime.datetime(2016, 3, 20, 9, 30)

strptime()函数用法

pandas中的时间序列

时间戳Timestamp

dates = [datetime(2016, 3, 1), datetime(2016, 3, 2), datetime(2016, 3, 3), datetime(2016, 3, 4)]
s = pd.Series(np.random.randn(4), index=dates)
s

运行结果为:
2016-03-01    1.650889
2016-03-02   -0.328463
2016-03-03    1.674872
2016-03-04   -0.310849
type(s.index[0])

运行结果为:
pandas.tslib.Timestamp

日期范围 date_range

生成日期范围

使用pd.date_range()函数

pd.date_range('20160320', '20160331')

运行结果为:
DatetimeIndex(['2016-03-20', '2016-03-21', '2016-03-22', '2016-03-23',
               '2016-03-24', '2016-03-25', '2016-03-26', '2016-03-27',
               '2016-03-28', '2016-03-29', '2016-03-30', '2016-03-31'],
              dtype='datetime64[ns]', freq='D')
pd.date_range(start='20160320', periods=10)

运行结果为:
DatetimeIndex(['2016-03-20', '2016-03-21', '2016-03-22', '2016-03-23',
               '2016-03-24', '2016-03-25', '2016-03-26', '2016-03-27',
               '2016-03-28', '2016-03-29'],
              dtype='datetime64[ns]', freq='D')
# normalize:若参数为True表示将start、end参数值正则化到午夜时间戳
pd.date_range(start='2016-03-20 16:23:32', periods=10, normalize=True)

运行结果为:
DatetimeIndex(['2016-03-20', '2016-03-21', '2016-03-22', '2016-03-23',
               '2016-03-24', '2016-03-25', '2016-03-26', '2016-03-27',
               '2016-03-28', '2016-03-29'],
              dtype='datetime64[ns]', freq='D')
时间频率 freq

freq默认为’D’

pd.date_range(start='20160320', periods=10, freq='W')

运行结果为:
DatetimeIndex(['2016-03-20', '2016-03-27', '2016-04-03', '2016-04-10',
               '2016-04-17', '2016-04-24', '2016-05-01', '2016-05-08',
               '2016-05-15', '2016-05-22'],
              dtype='datetime64[ns]', freq='W-SUN')

freq大全

时期

pd.Period 表示时期,比如几日,月或几个月等。比如用来统计每个月的销售额,就可以用时期作为单位。

时期创建及算术运算
p1 = pd.Period(2010)
p1

运行结果为:
Period('2010', 'A-DEC')

p2 = p1 + 2
p2

运行结果为:
Period('2012', 'A-DEC')
p1 = pd.Period(2016, freq='M')
p1

运行结果为:
Period('2016-01', 'M')

p1 + 3

运行结果为:
Period('2016-04', 'M')
时期序列
pd.period_range(start='2016-01', periods=12, freq='M')

运行结果为:
PeriodIndex(['2016-01', '2016-02', '2016-03', '2016-04', '2016-05', '2016-06',
             '2016-07', '2016-08', '2016-09', '2016-10', '2016-11', '2016-12'],
            dtype='int64', freq='M')
pd.period_range(start='2016-01', end='2016-10', freq='M')

运行结果为:
PeriodIndex(['2016-01', '2016-02', '2016-03', '2016-04', '2016-05', '2016-06',
             '2016-07', '2016-08', '2016-09', '2016-10'],
            dtype='int64', freq='M')
# 用字符串创建
index = pd.PeriodIndex(['2016Q1', '2016Q2', '2016Q3'], freq='Q-DEC')
index

运行结果为:
PeriodIndex(['2016Q1', '2016Q2', '2016Q3'], dtype='int64', freq='Q-DEC')
时期的频率转换 asfreq()
p = pd.Period('2016', freq='A-DEC')
p

运行结果为:
Period('2016', 'A-DEC')

p.asfreq('M', how='start')

运行结果为:
Period('2016-01', 'M')

p.asfreq('M', how='end')

运行结果为:
Period('2016-12', 'M')
p = pd.Period('2016-04', freq='M')
p

运行结果为:
Period('2016-04', 'M')

p.asfreq('A-DEC')

运行结果为:
Period('2016', 'A-DEC')

# 以年为周期,以一年中的 3 月份作为年的结束(财年)
p.asfreq('A-MAR')

运行结果为:
Period('2017', 'A-MAR')
季度时间频率

Pandas 支持 12 种季度型频率,从 Q-JAN 到 Q-DEC。

p = pd.Period('2016Q4', 'Q-JAN')
p

运行结果为:
Period('2016Q4', 'Q-JAN')
# 以 1 月份结束的财年中,2016Q4 的时期是指 2015-11-1 到 2016-1-31
p.asfreq('D', how='start'), p.asfreq('D', how='end')

运行结果为:
(Period('2015-11-01', 'D'), Period('2016-01-31', 'D'))
# 获取该季度倒数第二个工作日下午4点的时间戳
p4pm = (p.asfreq('B', how='end') - 1).asfreq('T', 'start') + 16 * 60
p4pm

运行结果为:
Period('2016-01-28 16:00', 'T')
# 转换为 timestamp
p4pm.to_timestamp()

运行结果为:
Timestamp('2016-01-28 16:00:00')
Timestamp 和 Period 相互转换
ts = pd.Series(np.random.randn(5), index = pd.date_range('2016-01-01', periods=5, freq='M'))
ts

运行结果为:
2016-01-31   -0.773323
2016-02-29    0.215953
2016-03-31    1.301631
2016-04-30   -0.066134
2016-05-31    1.651792
ts.to_period()

运行结果为:
2016-01   -0.773323
2016-02    0.215953
2016-03    1.301631
2016-04   -0.066134
2016-05    1.651792

可以转换时指定freq

ts = pd.Series(np.random.randn(5), index = pd.date_range('2016-12-29', periods=5, freq='D'))
ts

运行结果为:
2016-12-29   -0.110462
2016-12-30   -0.265792
2016-12-31   -0.382456
2017-01-01   -0.036111
2017-01-02   -1.029658
pts = ts.to_period(freq='M')
pts

运行结果为:
2016-12   -0.110462
2016-12   -0.265792
2016-12   -0.382456
2017-01   -0.036111
2017-01   -1.029658
# 转换回时间戳时,细部时间会丢失
pts.to_timestamp(how='end')

运行结果为:
2016-12-31   -0.110462
2016-12-31   -0.265792
2016-12-31   -0.382456
2017-01-31   -0.036111
2017-01-31   -1.029658

时间重采样

  • 高频率 -> 低频率 -> 降采样:5 分钟股票交易数据转换为日交易数据
  • 低频率 -> 高频率 -> 升采样
  • 其他重采样:每周三 (W-WED) 转换为每周五 (W-FRI)

resample

ts = pd.Series(np.random.randint(0, 50, 60), index=pd.date_range('2016-04-25 09:30', periods=60, freq='T'))

# 0-4 分钟为第一组
ts.resample('5min', how='sum')

运行结果为:
2016-04-25 09:30:00    139
2016-04-25 09:35:00    118
2016-04-25 09:40:00    110
2016-04-25 09:45:00    125
2016-04-25 09:50:00     88
2016-04-25 09:55:00     75
2016-04-25 10:00:00    122
2016-04-25 10:05:00    134
2016-04-25 10:10:00     96
2016-04-25 10:15:00    124
2016-04-25 10:20:00     86
2016-04-25 10:25:00    130
# label=right即label等于右区间边界点的值
ts.resample('5min', how='sum', label='right')

运行结果为:
2016-04-25 09:35:00    139
2016-04-25 09:40:00    118
2016-04-25 09:45:00    110
2016-04-25 09:50:00    125
2016-04-25 09:55:00     88
2016-04-25 10:00:00     75
2016-04-25 10:05:00    122
2016-04-25 10:10:00    134
2016-04-25 10:15:00     96
2016-04-25 10:20:00    124
2016-04-25 10:25:00     86
2016-04-25 10:30:00    130

OHLC

金融数据专用:Open/High/Low/Close

# 例:
ts.resample('5min', how='ohlc')

升采样和插值

# 以周为单位,每周五采样
df = pd.DataFrame(np.random.randint(1, 50, 2), index=pd.date_range('2016-04-22', periods=2, freq='W-FRI'))
df

在这里插入图片描述

df.resample('D')

在这里插入图片描述

df.resample('D', fill_method='ffill', limit=3)

在这里插入图片描述

df.resample('W-MON', fill_method='ffill')

在这里插入图片描述

通过groupby重采样

ts = pd.Series(np.random.randint(0, 50, 100), index=pd.date_range('2016-03-01', periods=100, freq='D'))

ts.groupby(lambda x: x.month).sum()

运行结果为:
3    759
4    648
5    748
6    172

或

ts.groupby(ts.index.to_period('M')).sum()

运行结果为:
2016-03    759
2016-04    648
2016-05    748
2016-06    172
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值