Pandas处理日期数据

Pandas处理日期数据

    • 依据前缀查询
    • 方便的获取周、月、季度
  • date_range() 函数
    • 连续日期 (连续日历日)
    • 中间隔一天
    • 工作日
    • 每月的第一天
    • 每月的最后一天
    • 季度末
    • freq参数表
  • 时间戳与格式化时间

Pandas时间官网文档:https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html

Pandas日期处理,可以将2018-01-01、1/1/2018等多种日期格式映射成统一的格式对象,在该对象上提供强大的功能支持。

几个概念:

  1. .to_datetime:pandas的一个函数,能将字符串、列表、series变成日期形式
  2. Timestamp:pandas表示日期的对象形式
  3. DatetimeIndex:pandas表示日期的对象列表形式

其中:

  • DatetimeIndex是Timestamp的列表形式
  • pd.to_datetime对单个日期字符串处理会得到Timestamp
  • pd.to_datetime对日期字符串列表处理会得到DatetimeIndex

Pandas处理日期数据_第1张图片
此部分来源于B站up主https://space.bilibili.com/61036655

import pandas as pd
df = pd.read_csv('F:\\Temp\\datas\\Tianqi_2018.csv')
df['time_copy'] = pd.to_datetime(df['time'])
df.set_index(pd.to_datetime(df["time"]), inplace=True)
print(df.head())
df.head() df.info()
Pandas处理日期数据_第2张图片 Pandas处理日期数据_第3张图片

将索引设置成时间格式,是为了方便的对DatetimeIndex进行查询。下面开始演示。

依据前缀查询

# 下面两行代码,哪怕索引不是datetime形式,也能查的出来
# 筛选固定的某一天
print(df.loc['2018-01-05'])
# 日期区间
print(df.loc['2018-01-05':'2018-01-10'])
# 按月份前缀筛选(若索引不是datetime形式的,会报错)
print(df.loc['2018-03'])

# 若是 print(df.loc[df['time_copy']=='2018-03'])   虽然数据类型没问题,但只能输出3月1号这一行的数据
# 注意括号位置  符号&不能替换为and
# 它与 df.loc[(df['time_copy']>='2018-03-01') & (df['time_copy']<='2018-03-31')] 结果一样,所以对于逻辑判断来说,数据类型不影响结果
print(df.loc[(df['time']>='2018-03-01') & (df['time']<='2018-03-31')])


# 按月份前缀筛选(若索引是字符串类型,那么只有2018-07-01到2018-08-31 62行)
print(df.loc["2018-07":"2018-09"])


# 按年份前缀筛选(若索引是字符串类型,直接报错)
print(df.loc["2018"])

方便的获取周、月、季度

https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#time-date-components

# 获取州 月 季度数字列表(这只对index有用,time_copy列不行)
print(df.index.week)
print(df.index.month)
print(df.index.quarter)

统计每周、每月、每个季度的最高温度(也可以统计最低均值)

# 统计每周的最高温
print(df.groupby(df.index.week)["bWendu"].max())

# 统计每月的最高温
print(df.groupby(df.index.month)["bWendu"].max())

# 统计每个季度的最高温
print(df.groupby(df.index.quarter)["bWendu"].max())

date_range() 函数

注意freq=的参数,本节末有参数表。
date_range()起止参数包括其自身。 也可以像Python的range()一样,使用closed参数(closed=‘left’ or closed=‘right’)

连续日期 (连续日历日)

import pandas as pd
print(pd.date_range(start='2021-6-1',end='2021-6-10'))
print()
print(pd.date_range(start='2021-6-1',periods=10))
'''
DatetimeIndex(['2021-06-01', '2021-06-02', '2021-06-03', '2021-06-04',
               '2021-06-05', '2021-06-06', '2021-06-07', '2021-06-08',
               '2021-06-09', '2021-06-10'],
              dtype='datetime64[ns]', freq='D')
'''

中间隔一天

import pandas as pd
print(pd.date_range(start='2021-6-1',end='2021-6-10', freq='2D'))
'''
DatetimeIndex(['2021-06-01', '2021-06-03', '2021-06-05', '2021-06-07',
               '2021-06-09'],
              dtype='datetime64[ns]', freq='2D')
'''

工作日

import pandas as pd
print(pd.date_range(start='2021-6-1',end='2021-6-10', freq='B'))
'''
DatetimeIndex(['2021-06-01', '2021-06-02', '2021-06-03', '2021-06-04',
               '2021-06-07', '2021-06-08', '2021-06-09', '2021-06-10'],
              dtype='datetime64[ns]', freq='B')
'''

每月的第一天

import pandas as pd
print(pd.date_range(start='2020-1-1',end='2020-12-31',freq='MS'))
'''
DatetimeIndex(['2020-01-01', '2020-02-01', '2020-03-01', '2020-04-01',
               '2020-05-01', '2020-06-01', '2020-07-01', '2020-08-01',
               '2020-09-01', '2020-10-01', '2020-11-01', '2020-12-01'],
              dtype='datetime64[ns]', freq='MS')
'''

每月的最后一天

import pandas as pd
print(pd.date_range(start='2020-1-1',end='2020-12-31',freq='M'))
'''
DatetimeIndex(['2020-01-31', '2020-02-29', '2020-03-31', '2020-04-30',
               '2020-05-31', '2020-06-30', '2020-07-31', '2020-08-31',
               '2020-09-30', '2020-10-31', '2020-11-30', '2020-12-31'],
              dtype='datetime64[ns]', freq='M')
'''

季度末

import pandas as pd
print(pd.date_range(start='2020-1-1',end='2020-12-31', freq='Q'))
'''
DatetimeIndex(['2020-03-31', '2020-06-30', '2020-09-30', '2020-12-31'], dtype='datetime64[ns]', freq='Q-DEC')
'''

freq参数表

官网:https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#offset-aliases

freq 描述 freq 描述 freq 描述
B 工作日频率 SMS 每半月第一个日历日(第 1 天和第 15 天) AS,YS 每年的第一个日历日
C 自定义工作日频率 BMS 每月第一个工作日 BAS,BYS 每年的第一个工作日
D 日历日频率 CBMS 自定义每月第一个工作日 BH 工作日按“时”的频率
W 每周频率 Q 季度最后一个月的最后一个日历日 H 每小时频率
M 月末频率 BQ 季度最后一个月的最后一个工作日 T,min 每分钟频率
SM 半月末频率(15 日和月末) QS 季度最后一个月的第一个日历日 S 秒频率
BM 每月最后一个工作日 BQS 季度最后一个月的第一个工作日 L,ms 毫秒频率
CBM 自定义每月最后一个工作日 A,Y 每年的最后一个日历日 U,us 微秒频率
MS 每月第一个日历日 BA,BY 每年的最后一个工作日 N 纳秒频率

时间戳与格式化时间

# 查看当前时间戳
import time
print(time.time())

时间戳转格式化时间

import pandas as pd
data = pd.DataFrame({
     'timeStamp':[1638432171, 1638432181, 1638432231, 1638432232, 1638435832],'sui':list('abcde')})
data['time1'] = pd.to_datetime(data['timeStamp'], unit="s")
data['time2'] = pd.to_datetime(data['timeStamp'].apply(lambda i:i+8*3600), unit="s")
print(data)
# 代码里的时间戳对应的是2021-12-02 16:02:51 ,但结果很显然差了八个小时。
# 因为to_datetime转换的是格林威治时间,比北京时间少八小时。所以要用的话要做个加法。
'''
    timeStamp  sui              time1                time2
0  1638432171   a   2021-12-02 08:02:51   2021-12-02 16:02:51
1  1638432181   b   2021-12-02 08:03:01   2021-12-02 16:03:01
2  1638432231   c   2021-12-02 08:03:51   2021-12-02 16:03:51
3  1638432232   d   2021-12-02 08:03:52   2021-12-02 16:03:52
4  1638435832   e   2021-12-02 09:03:52   2021-12-02 17:03:52
'''

格式化时间转时间戳

import pandas as pd
import time
data = pd.DataFrame({
     'time':['2021-12-02 16:10:30', '2021-12-02 16:10:31', '2021-12-02 16:11:31', '2021-12-02 16:11:30', '2021-12-02 17:10:30'],'sui':list('abcde')})
data['timeStamp1'] = data['time'].apply(lambda i:int(time.mktime(time.strptime(i, '%Y-%m-%d %H:%M:%S'))))
# 还有一种报警告的方法
data['date'] = pd.to_datetime(data['time'])
data['timeStamp2'] = data['date'].astype('int64')//1e9
data['timeStamp2'] = data['timeStamp2'].astype('int32')

print(data)

'''
                  time sui  timeStamp1                date  timeStamp2
0  2021-12-02 16:10:30   a  1638432630 2021-12-02 16:10:30  1638461430
1  2021-12-02 16:10:31   b  1638432631 2021-12-02 16:10:31  1638461431
2  2021-12-02 16:11:31   c  1638432691 2021-12-02 16:11:31  1638461491
3  2021-12-02 16:11:30   d  1638432690 2021-12-02 16:11:30  1638461490
4  2021-12-02 17:10:30   e  1638436230 2021-12-02 17:10:30  1638465030
'''

时间戳在线工具:https://tool.lu/timestamp/
从时间戳到纪元:https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#from-timestamps-to-epoch
今天发现,官网给了一个用格式化时间转时间戳的方式。但结果与下面的astype函数一致,都是快了8小时,所以用to_datetime转回来的时间就刚刚好。

import pandas as pd
# 生成4个间隔一分钟的连续时间
df = pd.DataFrame({
     'time': pd.date_range("2021-12-03 11:21:05", periods=4, freq="T")})

# 减去纪元(UTC 时间 1970 年 1 月 1 日午夜),然后除以“单位”(1 秒)。
df['guanwang'] = (df['time'] - pd.Timestamp("1970-01-01")) // pd.Timedelta("1s")

import time
df['zidingyi'] = df['time'].apply(lambda i:int(time.mktime(time.strptime(str(i), '%Y-%m-%d %H:%M:%S'))))

df['from_g'] = pd.to_datetime(df['guanwang'], unit="s")
df['from_z'] = pd.to_datetime(df['zidingyi'], unit="s")

print(df)

print(time.time())
'''
                 time    guanwang    zidingyi              from_g              from_z
0 2021-12-03 11:21:05  1638530465  1638501665 2021-12-03 11:21:05 2021-12-03 03:21:05
1 2021-12-03 11:22:05  1638530525  1638501725 2021-12-03 11:22:05 2021-12-03 03:22:05
2 2021-12-03 11:23:05  1638530585  1638501785 2021-12-03 11:23:05 2021-12-03 03:23:05
3 2021-12-03 11:24:05  1638530645  1638501845 2021-12-03 11:24:05 2021-12-03 03:24:05
1638501668.4354832
'''

此部分,可忽略。。。

用apply函数转换得到的时间戳1就是北京时间下的时间戳,但是用to_datetime转换之后又变为UTC时间。
用astype函数转换得到的时间戳2应该是北京时间下的时间戳加28800,所以用to_datetime转换之后刚好对应北京时间。但使用astype函数会报警告。

import pandas as pd
import time
data = pd.DataFrame({
     'time':['2021-12-02 16:10:30', '2021-12-02 16:10:31', '2021-12-02 16:11:31', '2021-12-02 16:11:30', '2021-12-02 17:10:30'],'sui':list('abcde')})
data['timeStamp1'] = data['time'].apply(lambda i:int(time.mktime(time.strptime(i, '%Y-%m-%d %H:%M:%S'))))
# 还有一种报警告的方法
data['date'] = pd.to_datetime(data['time'])
data['timeStamp2'] = data['date'].astype('int64')//1e9
data['timeStamp2'] = data['timeStamp2'].astype('int32')
# 时间戳1比时间戳2少了28800秒
data['cha'] = data['timeStamp1']-data['timeStamp2']

data['Time1'] = pd.to_datetime(data['timeStamp1'], unit="s")
data['Time2'] = pd.to_datetime(data['timeStamp2'], unit="s")

print(data)

'''
                  time sui  timeStamp1                date  timeStamp2    cha               Time1               Time2
0  2021-12-02 16:10:30   a  1638432630 2021-12-02 16:10:30  1638461430 -28800 2021-12-02 08:10:30 2021-12-02 16:10:30
1  2021-12-02 16:10:31   b  1638432631 2021-12-02 16:10:31  1638461431 -28800 2021-12-02 08:10:31 2021-12-02 16:10:31
2  2021-12-02 16:11:31   c  1638432691 2021-12-02 16:11:31  1638461491 -28800 2021-12-02 08:11:31 2021-12-02 16:11:31
3  2021-12-02 16:11:30   d  1638432690 2021-12-02 16:11:30  1638461490 -28800 2021-12-02 08:11:30 2021-12-02 16:11:30
4  2021-12-02 17:10:30   e  1638436230 2021-12-02 17:10:30  1638465030 -28800 2021-12-02 09:10:30 2021-12-02 17:10:30
'''

你可能感兴趣的:(#,Pandas,python,数据分析,pandas)