pandas datetime数据类型

datetime 数据类型

学习目标

  • 应用Pandas来处理日期时间类型数据

1 Python的datetime对象

  • Python内置了datetime对象,可以在datetime库中找到
from datetime import datetime
now = datetime.now()
now

显示结果:

datetime.datetime(2020, 6, 17, 19, 47, 56, 965416)
  • 还可以手动创建datetime
t1 = datetime.now()
t2 = datetime(2020,1,1)
diff = t1-t2
print(t2)
print(diff)

显示结果:

2020-01-01 00:00:00
518 days, 11:06:49.342877
  • 查看diff的数据类型
print(type(diff))

显示结果:

<class 'datetime.timedelta'>

2 将pandas中的数据转换成datetime

  • 可以使用to_datetime函数把数据转换成datetime类型
#加载数据 并把Date列转换为datetime对象
ebola = pd.read_csv('data/country_timeseries.csv')
#获取左上角数据
ebola.iloc[:5,:5]

显示结果:

DateDayCases_GuineaCases_LiberiaCases_SierraLeone
01/5/20152892776.0NaN10030.0
11/4/20152882775.0NaN9780.0
21/3/20152872769.08166.09722.0
31/2/2015286NaN8157.0NaN
412/31/20142842730.08115.09633.0
  • 从数据中看出 Date列是日期,但通过info查看加载后数据为object类型
ebola.info()

显示结果:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 122 entries, 0 to 121
Data columns (total 18 columns):
#   Column               Non-Null Count  Dtype  
---  ------               --------------  -----  
0   Date                 122 non-null    object 
1   Day                  122 non-null    int64  
2   Cases_Guinea         93 non-null     float64
3   Cases_Liberia        83 non-null     float64
4   Cases_SierraLeone    87 non-null     float64
5   Cases_Nigeria        38 non-null     float64
6   Cases_Senegal        25 non-null     float64
7   Cases_UnitedStates   18 non-null     float64
8   Cases_Spain          16 non-null     float64
9   Cases_Mali           12 non-null     float64
10  Deaths_Guinea        92 non-null     float64
11  Deaths_Liberia       81 non-null     float64
12  Deaths_SierraLeone   87 non-null     float64
13  Deaths_Nigeria       38 non-null     float64
14  Deaths_Senegal       22 non-null     float64
15  Deaths_UnitedStates  18 non-null     float64
16  Deaths_Spain         16 non-null     float64
17  Deaths_Mali          12 non-null     float64
dtypes: float64(16), int64(1), object(1)
memory usage: 17.3+ KB

  • 可以通过to_datetime方法把Date列转换为datetime,然后创建新列
ebola['date_dt'] = pd.to_datetime(ebola['Date'])
ebola.info()

显示结果:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 122 entries, 0 to 121
Data columns (total 19 columns):
#   Column               Non-Null Count  Dtype         
---  ------               --------------  -----         
0   Date                 122 non-null    object        
1   Day                  122 non-null    int64         
2   Cases_Guinea         93 non-null     float64       
3   Cases_Liberia        83 non-null     float64       
4   Cases_SierraLeone    87 non-null     float64       
5   Cases_Nigeria        38 non-null     float64       
6   Cases_Senegal        25 non-null     float64       
7   Cases_UnitedStates   18 non-null     float64       
8   Cases_Spain          16 non-null     float64       
9   Cases_Mali           12 non-null     float64       
10  Deaths_Guinea        92 non-null     float64       
11  Deaths_Liberia       81 non-null     float64       
12  Deaths_SierraLeone   87 non-null     float64       
13  Deaths_Nigeria       38 non-null     float64       
14  Deaths_Senegal       22 non-null     float64       
15  Deaths_UnitedStates  18 non-null     float64       
16  Deaths_Spain         16 non-null     float64       
17  Deaths_Mali          12 non-null     float64       
18  date_dt              122 non-null    datetime64[ns]
dtypes: datetime64[ns](1), float64(16), int64(1), object(1)
memory usage: 18.2+ KB

  • 如果数据中包含日期时间数据,也可以在加载的时候,通过parse_dates参数指定时间字段所在列的下标
ebola = pd.read_csv('data/country_timeseries.csv', parse_dates=[0]) 
ebola.info()

显示结果:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 122 entries, 0 to 121
Data columns (total 18 columns):
#   Column               Non-Null Count  Dtype         
---  ------               --------------  -----         
0   Date                 122 non-null    datetime64[ns]
1   Day                  122 non-null    int64         
2   Cases_Guinea         93 non-null     float64       
3   Cases_Liberia        83 non-null     float64       
4   Cases_SierraLeone    87 non-null     float64       
5   Cases_Nigeria        38 non-null     float64       
6   Cases_Senegal        25 non-null     float64       
7   Cases_UnitedStates   18 non-null     float64       
8   Cases_Spain          16 non-null     float64       
9   Cases_Mali           12 non-null     float64       
10  Deaths_Guinea        92 non-null     float64       
11  Deaths_Liberia       81 non-null     float64       
12  Deaths_SierraLeone   87 non-null     float64       
13  Deaths_Nigeria       38 non-null     float64       
14  Deaths_Senegal       22 non-null     float64       
15  Deaths_UnitedStates  18 non-null     float64       
16  Deaths_Spain         16 non-null     float64       
17  Deaths_Mali          12 non-null     float64       
dtypes: datetime64[ns](1), float64(16), int64(1)
memory usage: 17.3 KB

3 提取日期的各个部分

  • 获取了一个datetime对象,就可以提取日期的各个部分了
d = pd.to_datetime('2020-06-20')
d

显示结果:

Timestamp('2020-06-20 00:00:00')

  • 可以看到得到的数据是Timestamp类型,通过Timestamp可以获取年,月,日等部分
print(d.year)
print(d.month)
print(d.day)

显示结果:

2020
6
20

  • 通过ebola数据集的Date列,创建新列year
ebola['year'] = ebola['Date'].dt.year
ebola['year']

显示结果:

0      2015
1      2015
2      2015
3      2015
4      2014
  ... 
117    2014
118    2014
119    2014
120    2014
121    2014
Name: year, Length: 122, dtype: int64

ebola['month'], ebola['day']  = (ebola['Date'].dt.month, ebola['Date'].dt.day)
ebola[['Date','year','month','day']].head()

显示结果:

Dateyearmonthday
02015-01-05201515
12015-01-04201514
22015-01-03201513
32015-01-02201512
42014-12-3120141231
ebola.info()

显示结果:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 122 entries, 0 to 121
Data columns (total 21 columns):
#   Column               Non-Null Count  Dtype         
---  ------               --------------  -----         
0   Date                 122 non-null    datetime64[ns]
1   Day                  122 non-null    int64         
2   Cases_Guinea         93 non-null     float64       
3   Cases_Liberia        83 non-null     float64       
4   Cases_SierraLeone    87 non-null     float64       
5   Cases_Nigeria        38 non-null     float64       
6   Cases_Senegal        25 non-null     float64       
7   Cases_UnitedStates   18 non-null     float64       
8   Cases_Spain          16 non-null     float64       
9   Cases_Mali           12 non-null     float64       
10  Deaths_Guinea        92 non-null     float64       
11  Deaths_Liberia       81 non-null     float64       
12  Deaths_SierraLeone   87 non-null     float64       
13  Deaths_Nigeria       38 non-null     float64       
14  Deaths_Senegal       22 non-null     float64       
15  Deaths_UnitedStates  18 non-null     float64       
16  Deaths_Spain         16 non-null     float64       
17  Deaths_Mali          12 non-null     float64       
18  year                 122 non-null    int64         
19  month                122 non-null    int64         
20  day                  122 non-null    int64         
dtypes: datetime64[ns](1), float64(16), int64(4)
memory usage: 20.1 KB

4 日期运算和Timedelta

4.1 datetime类型的日期可以直接进行时间计算

Ebola数据集中的Day列表示一个国家爆发Ebola疫情的天数。这一列数据可以通过日期运算重建该列

  • 疫情爆发的第一天(数据集中最早的一天)是2014-03-22。计算疫情爆发的天数时,只需要用每个日期减去这个日期即可
# 获取疫情爆发的第一天
ebola['Date'].min()

显示结果:

Timestamp('2014-03-22 00:00:00')

  • 添加爆发时长列
ebola['outbreak_d'] = ebola['Date'] - ebola['Date'].min()
ebola[['Date','Day','outbreak_d']].head()

显示结果:

DateDayoutbreak_d
02015-01-05289289 days
12015-01-04288288 days
22015-01-03287287 days
32015-01-02286286 days
42014-12-31284284 days
  • 查看最后五行数据
ebola[['Date','Day','outbreak_d']].tail()

显示结果:

DateDayoutbreak_d
1172014-03-2755 days
1182014-03-2644 days
1192014-03-2533 days
1202014-03-2422 days
1212014-03-2200 days
  • 执行这种日期运算,会得到一个timedelta对象
ebola.info()

显示结果:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 122 entries, 0 to 121
Data columns (total 22 columns):
#   Column               Non-Null Count  Dtype          
---  ------               --------------  -----          
0   Date                 122 non-null    datetime64[ns] 
1   Day                  122 non-null    int64          
2   Cases_Guinea         93 non-null     float64        
3   Cases_Liberia        83 non-null     float64        
4   Cases_SierraLeone    87 non-null     float64        
5   Cases_Nigeria        38 non-null     float64        
6   Cases_Senegal        25 non-null     float64        
7   Cases_UnitedStates   18 non-null     float64        
8   Cases_Spain          16 non-null     float64        
9   Cases_Mali           12 non-null     float64        
10  Deaths_Guinea        92 non-null     float64        
11  Deaths_Liberia       81 non-null     float64        
12  Deaths_SierraLeone   87 non-null     float64        
13  Deaths_Nigeria       38 non-null     float64        
14  Deaths_Senegal       22 non-null     float64        
15  Deaths_UnitedStates  18 non-null     float64        
16  Deaths_Spain         16 non-null     float64        
17  Deaths_Mali          12 non-null     float64        
18  year                 122 non-null    int64          
19  month                122 non-null    int64          
20  day                  122 non-null    int64          
21  outbreak_d           122 non-null    timedelta64[ns]
dtypes: datetime64[ns](1), float64(16), int64(4), timedelta64[ns](1)
memory usage: 21.1 KB

4.2 练习

需求:通过data/banklist.csv数据,计算每个季度、每年银行破产的数量

  • 加载data/banklist.csv数据
banks = pd.read_csv('data/banklist.csv')
banks.head()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1eSNas6o-1630672699322)(./img/时间数据类型-01.png)]

  • 可以看到有两列数据是日期时间类型,可以在导入数据的时候直接解析日期
banks = pd.read_csv('data/banklist.csv',parse_dates=[5,6])
banks.info()

显示结果:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 553 entries, 0 to 552
Data columns (total 7 columns):
#   Column                 Non-Null Count  Dtype         
---  ------                 --------------  -----         
0   Bank Name              553 non-null    object        
1   City                   553 non-null    object        
2   ST                     553 non-null    object        
3   CERT                   553 non-null    int64         
4   Acquiring Institution  553 non-null    object        
5   Closing Date           553 non-null    datetime64[ns]
6   Updated Date           553 non-null    datetime64[ns]
dtypes: datetime64[ns](2), int64(1), object(4)
memory usage: 30.4+ KB

  • 添加两列,分别表示银行破产的季度和年份
banks['closing_quarter'], banks['closing_year'] = (banks['Closing Date'].dt.quarter, banks['Closing Date'].dt.year)
banks.head()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rQ3OFxfZ-1630672699325)(./img/时间数据类型-02.png)]

  • 可以根据新添加的两列,计算每年破产银行数量
# 根据closing_year分组,再计算每组数据的行数
closing_year = banks.groupby(['closing_year']).size()
closing_year

显示结果:

closing_year
2000      2
2001      4
2002     11
2003      3
2004      4
2007      3
2008     25
2009    140
2010    157
2011     92
2012     51
2013     24
2014     18
2015      8
2016      5
2017      6
dtype: int64

  • 出图
closing_year.plot()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DOaQTTeV-1630672699327)(./img/时间数据类型-03.png)]

  • 计算每年每季度破产银行数量,并出图
closing_year_q = banks.groupby(['closing_year', 'closing_quarter']).size()
closing_year_q.plot()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PCmLtn0G-1630672699329)(./img/时间数据类型-04.png)]

5 时间数据索引

股票价格是包含日期的典型数据,以data/TSLA.csv为例

5.1 加载数据

  • 加载特斯拉股票数据
tesla = pd.read_csv('data/TSLA.csv')
tesla

显示结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Tkg6Ias8-1630672699330)(./img/tsl-01.png)]

  • 可以看出,tesla股票数据中第一列为日期,在加载数据的时候,可以直接解析日期数据
tesla = pd.read_csv('data/TSLA.csv', parse_dates=[0])
tesla.info()

显示结果:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1215 entries, 0 to 1214
Data columns (total 7 columns):
#   Column     Non-Null Count  Dtype         
---  ------     --------------  -----         
0   Date       1215 non-null   datetime64[ns]
1   High       1215 non-null   float64       
2   Low        1215 non-null   float64       
3   Open       1215 non-null   float64       
4   Close      1215 non-null   float64       
5   Volume     1215 non-null   int64         
6   Adj Close  1215 non-null   float64       
dtypes: datetime64[ns](1), float64(5), int64(1)
memory usage: 66.6 KB

  • 转换为时间类型后,就可以基于日期数据获取数据子集,比如要获取2015年8月的股票数据
tesla.loc[(tesla.Date.dt.year==2015) & (tesla.Date.dt.month==8)]

显示结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zq9IKrnb-1630672699331)(./img/tsl-02.png)]

5.2 DatetimeIndex对象

  • 在处理包含datetime的数据时,经常需要把datetime对象设置成DateFrame的索引
#首先把Date列指定为索引
tesla.index = tesla['Date']
tesla.index

显示结果:

DatetimeIndex(['2015-08-19', '2015-08-20', '2015-08-21', '2015-08-24',
          '2015-08-25', '2015-08-26', '2015-08-27', '2015-08-28',
          '2015-08-31', '2015-09-01',
          ...
          '2020-06-03', '2020-06-04', '2020-06-05', '2020-06-08',
          '2020-06-09', '2020-06-10', '2020-06-11', '2020-06-12',
          '2020-06-15', '2020-06-16'],
         dtype='datetime64[ns]', name='Date', length=1215, freq=None)

  • 查看数据集
tesla.head()

显示结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zUMFWm6F-1630672699332)(./img/tsl-03.png)]

  • 把索引设置为日期对象后,可以直接使用日期中的年份来获取数据
tesla['2016'].iloc[:5] # 数据的日期索引为有序的才能使用此方法查询

显示结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tXRsugJg-1630672699333)(./img/tsl-04.png)]

  • 也可以根据年份和月份获取数据
tesla['2016-06'].iloc[:5]

显示结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e6yQWirh-1630672699334)(./img/tsl-05.png)]

5.3 TimedeltaIndex对象

  • 首先创建一个timedelta
tesla['ref_date'] = tesla['Date'] - tesla['Date'].min()
tesla['ref_date'] 

显示结果:

Date
2015-08-19      0 days
2015-08-20      1 days
2015-08-21      2 days
2015-08-24      5 days
2015-08-25      6 days
           ...   
2020-06-10   1757 days
2020-06-11   1758 days
2020-06-12   1759 days
2020-06-15   1762 days
2020-06-16   1763 days
Name: ref_date, Length: 1215, dtype: timedelta64[ns]

  • 把timedelta设置为index
tesla.index = tesla['ref_date'] 
tesla.info()

显示结果:

<class 'pandas.core.frame.DataFrame'>
TimedeltaIndex: 1215 entries, 0 days to 1763 days
Data columns (total 8 columns):
#   Column     Non-Null Count  Dtype          
---  ------     --------------  -----          
0   Date       1215 non-null   datetime64[ns] 
1   High       1215 non-null   float64        
2   Low        1215 non-null   float64        
3   Open       1215 non-null   float64        
4   Close      1215 non-null   float64        
5   Volume     1215 non-null   int64          
6   Adj Close  1215 non-null   float64        
7   ref_date   1215 non-null   timedelta64[ns]
dtypes: datetime64[ns](1), float64(5), int64(1), timedelta64[ns](1)
memory usage: 85.4 KB

tesla.head()

显示结果:

DateHighLowOpenCloseVolumeAdj Closeref_date
ref_date
0 days2015-08-19260.649994255.020004260.329987255.2500003604300255.2500000 days
1 days2015-08-20254.559998241.899994252.059998242.1799934905800242.1799931 days
2 days2015-08-21243.800003230.509995236.000000230.7700046590200230.7700042 days
5 days2015-08-24231.399994195.000000202.789993218.8699959581600218.8699955 days
6 days2015-08-25230.899994219.119995230.520004220.0299994327300220.0299996 days
  • 可以基于ref_date来选择数据
tesla['0 days':'4 days']

显示结果:

DateHighLowOpenCloseVolumeAdj Closeref_date
ref_date
0 days2015-08-19260.649994255.020004260.329987255.2500003604300255.2500000 days
1 days2015-08-20254.559998241.899994252.059998242.1799934905800242.1799931 days
2 days2015-08-21243.800003230.509995236.000000230.7700046590200230.7700042 days

6 日期范围

  • 包含日期的数据集中,并非每一个都包含固定频率。比如在Ebola数据集中,日期并没有规律
ebola.iloc[:,:5]

显示结果:

DateDayCases_GuineaCases_LiberiaCases_SierraLeone
02015-01-052892776.0NaN10030.0
12015-01-042882775.0NaN9780.0
22015-01-032872769.08166.09722.0
32015-01-02286NaN8157.0NaN
42014-12-312842730.08115.09633.0
1172014-03-275103.08.06.0
1182014-03-26486.0NaNNaN
1192014-03-25386.0NaNNaN
1202014-03-24286.0NaNNaN
1212014-03-22049.0NaNNaN
  • 从上面的数据中可以看到,缺少2015年1月1日,2014年3月23日,如果想让日期连续,可以创建一个日期范围来为数据集重建索引。这时,我们可以使用df.date_range()函数来创建连续的日期范围
head_range = pd.date_range(start='2014-12-31', end='2015-01-05')
head_range

显示结果:

DatetimeIndex(['2014-12-31', '2015-01-01', '2015-01-02', '2015-01-03',
               '2015-01-04', '2015-01-05'],
              dtype='datetime64[ns]', freq='D')

  • 在上面的例子中,只取前5行,首先设置日期索引,然后为数据重建连续索引
ebola_5 = ebola.head()
ebola_5.index = ebola_5['Date']
ebola_5.reindex(head_range)
ebola_5.iloc[:,:5]

显示结果:

DateDayCases_GuineaCases_LiberiaCases_SierraLeone
2014-12-312014-12-31284.02730.08115.09633.0
2015-01-01NaTNaNNaNNaNNaN
2015-01-022015-01-02286.0NaN8157.0NaN
2015-01-032015-01-03287.02769.08166.09722.0
2015-01-042015-01-04288.02775.0NaN9780.0
2015-01-052015-01-05289.02776.0NaN10030.0
  • 使用date_range函数创建日期序列时,可以传入一个参数freq,默认情况下freq取值为D,表示日期范围内的值是逐日递增的。
# 2020年1月1日这周所有的工作日,freq='B'表示取工作日,freq默认为'D'返回全部日期
pd.date_range('2020-01-01', '2020-01-07', freq='B')

显示结果:从结果中看到生成的日期中缺少1月4日,1月5日,为休息日

DatetimeIndex(['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-06',
               '2020-01-07'],
              dtype='datetime64[ns]', freq='B')

  • 【查表】freq的可选参数
freq参数的可能取值
AliasDescription
B工作日
C自定义工作日
D日历日
W每周
M月末
SM月中和月末(每月第15天和月末)
BM月末工作日
CBM自定义月末工作日
MS月初
SMS月初和月中(每月第1天和第15天)
BMS月初工作日
CBMS自定义月初工作日
Q季度末
BQ季度末工作日
QS季度初
BQS季度初工作日
A, Y年末
BA, BY年末工作日
AS, YS年初
BAS, BYS年初工作日
BH工作时间
H小时
T, min分钟
S
L, ms毫秒
U, usmicroseconds
N纳秒
  • 在freq传入参数的基础上,可以做一些调整
# 隔一个工作日取一个工作日
pd.date_range('2020-01-01', '2020-01-07', freq='2B')

显示结果:

DatetimeIndex(['2020-01-01', '2020-01-03', '2020-01-07'], dtype='datetime64[ns]', freq='2B')

  • freq传入的参数可以传入多个
#2020年每个月的第一个星期四
pd.date_range('2020-01-01','2020-12-31',freq='WOM-1THU')

显示结果:

DatetimeIndex(['2020-01-02', '2020-02-06', '2020-03-05', '2020-04-02',
               '2020-05-07', '2020-06-04', '2020-07-02', '2020-08-06',
               '2020-09-03', '2020-10-01', '2020-11-05', '2020-12-03'],
              dtype='datetime64[ns]', freq='WOM-1THU')

#每个月的第三个星期五
pd.date_range('2020-01-01','2020-12-31',freq='WOM-3FRI')

显示结果:

DatetimeIndex(['2020-01-17', '2020-02-21', '2020-03-20', '2020-04-17',
               '2020-05-15', '2020-06-19', '2020-07-17', '2020-08-21',
               '2020-09-18', '2020-10-16', '2020-11-20', '2020-12-18'],
              dtype='datetime64[ns]', freq='WOM-3FRI')

7 datetime类型案例

  • 加载丹佛市犯罪记录数据集
crime = pd.read_csv('data/crime.csv',parse_dates=['REPORTED_DATE'])
crime

显示结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YfDOrYiP-1630672699334)(./img/时间数据类型-05.png)]

  • 查看数据集总体情况
crime.info()

显示结果:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 460911 entries, 0 to 460910
Data columns (total 8 columns):
#   Column               Non-Null Count   Dtype         
---  ------               --------------   -----         
0   OFFENSE_TYPE_ID      460911 non-null  object        
1   OFFENSE_CATEGORY_ID  460911 non-null  object        
2   REPORTED_DATE        460911 non-null  datetime64[ns]
3   GEO_LON              457296 non-null  float64       
4   GEO_LAT              457296 non-null  float64       
5   NEIGHBORHOOD_ID      460911 non-null  object        
6   IS_CRIME             460911 non-null  int64         
7   IS_TRAFFIC           460911 non-null  int64         
dtypes: datetime64[ns](1), float64(2), int64(2), object(3)
memory usage: 28.1+ MB

  • 设置报警时间为索引
crime = crime.set_index('REPORTED_DATE')
crime.head()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HRSSzKzT-1630672699335)(./img/时间数据类型-06.png)]

  • 查看某一天的报警记录
crime.loc['2016-05-12'] # 日期索引为无序的,只能通过loc获取数据

显示结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UWLLJafK-1630672699336)(./img/时间数据类型-07.png)]

  • 查看某一段时间的犯罪记录
crime.loc['2015-3-4':'2016-1-1'].sort_index()

显示结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VpoZZOko-1630672699336)(./img/时间数据类型-08.png)]

  • 时间段可以包括小时分钟
crime.loc['2015-3-4 22': '2016-1-1 23:45:00'].sort_index()

显示结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gbdQRIhd-1630672699337)(./img/时间数据类型-09.png)]

  • 查询凌晨两点到五点的报警记录
    • between_time函数
# between_time函数,include_end=False表示不包含结束时间,默认为True,同样也有include_start参数
crime.between_time('4:00', '5:00', include_end=False).head(10)

显示结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F4tJhgiX-1630672699337)(./img/时间数据类型-10.png)]

  • 查看发生在某个时刻的犯罪记录
    • at_time函数
crime.at_time('5:47')

显示结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ah0q5DpO-1630672699338)(./img/时间数据类型-11.png)]

  • 当数据量庞大时,在按时间段选取数据时,可以将时间索引排序,排序之后再选取效率更高
# sort_index() 对索引进行排序,默认升序
crime_sort = crime.sort_index()

  • 计算每周的犯罪数量
    • resample函数,传入'W'参数表示按周对时间索引进行分组
# resample函数传入W参数,表示按周分组,size查看分组后每组数量行数
weekly_crimes = crime_sort.resample('W').size()
weekly_crimes

显示结果:

REPORTED_DATE
2012-01-08     877
2012-01-15    1071
2012-01-22     991
2012-01-29     988
2012-02-05     888
         ... 
2017-09-03    1956
2017-09-10    1733
2017-09-17    1976
2017-09-24    1839
2017-10-01    1059
Freq: W-SUN, Length: 300, dtype: int64

  • 检验分组结果:查看起始数据到2012-1-8的报警记录数量
len(crime_sort.loc[:'2012-1-8'])

显示结果:

877

  • 检验分组结果:查看2012-1-9到2012-1-15的报警记录数量
len(crime_sort.loc['2012-1-9':'2012-1-15'])

显示结果:

1071

  • 也可以把周四作为每周的结束
crime_sort.resample('W-THU').size()

显示结果:

REPORTED_DATE
2012-01-05     462
2012-01-12    1116
2012-01-19     924
2012-01-26    1061
2012-02-02     926
         ... 
2017-09-07    1803
2017-09-14    1866
2017-09-21    1926
2017-09-28    1720
2017-10-05      28
Freq: W-THU, Length: 301, dtype: int64

  • 将按周分组结果可视化
# 去除warnning警告信息
import matplotlib as mpl
mpl.rcParams['font.sans-serif'] = ['KaiTi', 'SimHei', 'FangSong']  # 汉字字体,优先使用楷体,如果找不到楷体,则使用黑体
mpl.rcParams['font.size'] = 12  # 字体大小
mpl.rcParams['axes.unicode_minus'] = False  # 正常显示负号
# 出图
weekly_crimes.plot(figsize=(16,4), title='丹佛报警情况')

显示结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ts0YcYvw-1630672699339)(./img/时间数据类型-12.png)]

  • 分别统计每季度的犯罪和交通事故报警次数
# resample('Q')按季度分组数据后,提取['IS_CRIME', 'IS_TRAFFIC']字段,并对提取的列的值做sum求和计算
crime_quarterly = crime_sort.resample('Q')['IS_CRIME', 'IS_TRAFFIC'].sum()
crime_quarterly

显示结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sW8JBGPi-1630672699339)(./img/时间数据类型-13.png)]

  • resample('Q')统计的所有日期都是该季度的最后一天,使用QS参数生成每季度的第一天
crime_sort.resample('QS')['IS_CRIME', 'IS_TRAFFIC'].sum().head()

显示结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QbpiaKDN-1630672699340)(./img/时间数据类型-14.png)]

  • 结果可视化
plot_kwargs = dict(figsize=(16,4), color=['black', 'blue'], title='丹佛犯罪和交通事故数据')
crime_quarterly.plot(**plot_kwargs)

显示结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oRhpDuwz-1630672699340)(./img/时间数据类型-15.png)]

  • 分析工作日的犯罪情况:可以通过Timestamp的dt属性得到周几,然后统计
    • DatetimeIndex.dt.weekday可以返回日期是星期几
crime = pd.read_csv('data/crime.csv', parse_dates=['REPORTED_DATE'])
wd_counts = crime['REPORTED_DATE'].dt.weekday.value_counts()
wd_counts

显示结果:

0    70024
4    69621
2    69538
3    69287
1    68394
5    58834
6    55213
Name: REPORTED_DATE, dtype: int64

  • 出图
wd_counts.plot(kind='barh', title='星期一~星期日丹佛犯罪和交通事故报警数量统计')

显示结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MEI3OZrd-1630672699341)(./img/时间数据类型-16.png)]

小结

  • Pandas中,datetime64用来表示时间序列类型
  • 时间序列类型的数据可以作为行索引,对应的数据类型是DatetimeIndex类型
  • datetime64类型可以做差,返回的是Timedelta类型
  • 转换成时间序列类型后,可以按照时间的特点对数据进行处理
    • 提取日期的各个部分(月,日,星期…)
    • 进行日期运算
    • 按照日期范围取值
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值