获取程序运行的时间
打印时间
import datetime
print('start:',datetime.datetime.now().strftime("%Y.%m.%d-%H:%M:%S:%f"))
print('end:',datetime.datetime.now().strftime("%Y.%m.%d-%H:%M:%S:%f"))
魔法命令
%%time
将会给出运行整个cell的代码所花费的时间
%%time
time.sleep(5)
# CPU times: user 711 µs, sys: 710 µs, total: 1.42 ms
# Wall time: 5 s
%time
将会给出运行当前行的代码所花费的时间
%time time.sleep(5)
# CPU times: user 471 µs, sys: 1.11 ms, total: 1.58 ms
# Wall time: 5.01 s
DataFrame 中的 datetime 数据类型
格式转换
pd.to_datetime(df['日期'])
- 对于字符串格式的数据,基本都可以识别,如:‘2021-01-01’, ‘2021/01/01’, ‘20210101’, ‘2021-01-01 01:00:00’
- 对于数值型的20210101这种格式,就得使用参数
format='%Y%m%d'
常用用法
#提取日期和时间,使用的时候直接赋值就行了
df['日期'].dt.date
df['日期'].dt.time
#提取年月日时分秒,可按需求生成对应列
df['日期'].dt.year
df['日期'].dt.month
df['日期'].dt.day
df['日期'].dt.hour
df['日期'].dt.minute
注意:
df['单据日期'].dt.date
得到的,是一个object类型,但是,进行切片后,得到的确是datetime.date(2020, 11, 14)
所以,后续可以使用逻辑判断符进行逻辑判断:
df[df['日期']>datetime.date(2021, 1, 21)]
注:
实际上,即使是字符串类型的时间,也可以直接使用逻辑判断符进行这样的判断:
data_all.query('日付>="2020-07-01"')
data_all[data_all['日付']>="2020-07-01"]
‘年月日’转换成‘年月’或‘年周’
‘年月日’转换成‘年月’
# 方法一:
df['year'] = df['date'].dt.year
df['mon'] = df['date'].dt.month
df['year_mon'] = df['year'] * 100 + df['mon']
# 方法二:
df['year_mon'] = df['date'].dt.strftime('%Y%m')
‘年月日’转换成‘年周’
df['year'] = df['date'].dt.isocalendar().year
df['week'] = df['date'].dt.isocalendar().week
df['year_week'] = df['year'] * 100 + week_time['week']
转换成年周要尤其注意一点,假设,20200101是2019年的第52周,最终的结果就应该是201952
另外,使用加法运算进行拼接的‘年月’和‘年周’,其数据类型应该是numpy.int
,有其他用途时要转成int
型。
使用场景
若DataFrame中只有年、月、日、小时这样单独的列,且数据类型是数值型时,我们可以先将数值型数据转化为字符串型,然后用字符串拼接的方式拼出 “年-月-日”“ 时-分-秒”的格式,再用pd.to_datetime的方法。
- 数值型转化为字符串型
#数值型转化为字符串型
df_new['year'] = df_new['year'].apply(str)
df_new['month'] = df_new['month'].apply(str)
df_new['day'] = df_new['day'].apply(str)
df_new['hour'] = df_new['hour'].apply(str)
- 合并字符串
单个字符串的操作方法在DataFrame列与列之间也可以直接使用
df_new["时间"]=df_new['year']+'-'+df_new['month']+'-'+df_new['day']+' '+df_new['hour']+':'+'00'+":"+'00'
- pd.to_datetime
df_new['时间']=pd.to_datetime(df_new['时间'])
- 求时间间隔
# 求前后的时间间隔
# df['购买时间']已经做了排序处理
# df['购买时间']中的时间格式是'20200504',使用format参数告知函数应该如何处理
# datetime相减后得到的是timedelta对象(数据类型是timedelta64[ns]),所以使用.days属性获取天数
pd.to_datetime(df['购买时间'], format='%Y%m%d').diff().dt.days
from datetime import datetime
# 求'日期'列中的日期,和2020年8月31日的时间间隔
# '日期'列中的日期格式为'%Y-%m-%d'
df['日期'].apply(lambda x: datetime(2020,8,31) - datetime.strptime(x, '%Y-%m-%d')).dt.days
- 注意
日期时间格式虽然进行相关的时间操作非常方便,但日期格式不能进行相关性分析,这是一个弊端
获取月份第一天和最后一天
from datetime import datetime
import calendar
def getMonthFirstDayAndLastDay(year=None, month=None):
"""
:param year: 年份,默认是本年,可传int或str类型
:param month: 月份,默认是本月,可传int或str类型
:return: firstDay: 当月的第一天,datetime.date类型
lastDay: 当月的最后一天,datetime.date类型
"""
if year:
year = int(year)
else:
year = datetime.now().year
if month:
month = int(month)
else:
month = datetime.now().month
# 获取当月第一天的星期和当月的总天数
firstDayWeekDay, monthRange = calendar.monthrange(year, month)
# 获取当月的第一天
firstDay = datetime.date(datetime(year=year, month=month, day=1))
lastDay = datetime.date(datetime(year=year, month=month, day=monthRange))
return firstDay, lastDay
这个函数默认返回一个元组,可以通过切片获取自己需要的信息
时间之间的算术运算
获取两个日期之间的月份差
#获取两个日期之间的月份差
from datetime import datetime
def months_sub(str1,str2): #这里输入的日期格式是"%Y%m%d"
year1=datetime.strptime(str1[0:8],"%Y%m%d").year
year2=datetime.strptime(str2[0:8],"%Y%m%d").year
month1=datetime.strptime(str1[0:8],"%Y%m%d").month
month2=datetime.strptime(str2[0:8],"%Y%m%d").month
num=(year1-year2)*12+(month1-month2)
return num
#我们当然可以对输入的日期格式进行调整,比如输入"%Y-%m-%d",但相应的字符串的切片就要变成[0:10]
月份相加减
- 年月日
from datetime import datetime
from dateutil.relativedelta import relativedelta
(datetime(2019,1,12) + relativedelta(months=3)).strftime('%Y%m%d')
#月份的加减可以作用到年份上,实现跨年的功能
- 年月
from dateutil.relativedelta import relativedelta
value = '201101'
(datetime.datetime.strptime(value, '%Y%m') - relativedelta(months=1)).strftime('%Y%m')
# '201012'
获取两个日期相差的天数
# 前提:二者的数据类型必须是datetime,如果不是,先使用pd.to_datetime()进行转换
(df['日期01'] - df['日期02']).apply(lambda x:x.days)
如果数据量特别大的时候运行会很慢,因为apply毕竟只是沿着轴向逐个运算,类似循环操作。
更快的方法
(df['日期01'] - df['日期02']).dt.days
日期的相加减
import datetime
pd.to_datetime(df['日期']) - datetime.timedelta(30)
# 依旧符合广播的规则
获取周数
Year_week_day = pd.DataFrame(map(lambda x: x.isocalendar(),df['日期']),columns=['年号','第几周','第几天'])
Year_week_day
时间型与字符串型的相互转化
- 时间型转变为字符串
from datetime import datetime
# 方法一
str(datetime(2011, 1, 3))
# 方法二
datetime(2011, 1, 3).strftime('%Y-%m-%d')
# 在表格中的操作
df['时间'] = df['时间'].apply(lambda x: x.strftime('%Y-%m-%d'))
df['时间'] = df['时间'].dt.strftime('%Y-%m-%d')
- 字符串转变成时间型
from datetime import datetime
# 方法一
value = '2011-01-03'
datetime.strptime(value, '%Y-%m-%d') #'%Y-%m-%d'是用来解析'2011-01-03'的各部分意味着什么
# 方法二
from dateutil.parser import parse
parse('2011-01-03')
# 方法三
pd.to_datetime('2020-05-07')