使用Pandas?實(shí)現(xiàn)MySQL日期函數(shù)的解決方法
一、前言
環(huán)境:
windows11 64位
Python3.9
MySQL8
pandas1.4.2
本文主要介紹 MySQL 中的日期函數(shù)date_add()/date_sub()
、date_format()
、year()/month()/day()/hour()/minute()/second()
、datediff()
、datepart()
、from_unixtime()
、unix_timestamp()
如何使用pandas實(shí)現(xiàn),同時(shí)二者又有什么區(qū)別。
注:Python是很靈活的語言,達(dá)成同一個(gè)目標(biāo)或有多種途徑,我提供的只是其中一種解決方法,大家有其他的方法也歡迎留言討論。
二、語法對(duì)比
數(shù)據(jù)表
本次使用的數(shù)據(jù)如下。
使用 Python 構(gòu)建該數(shù)據(jù)集的語法如下:
import pandas as pd import numpy as np df1 = pd.DataFrame({ 'col1' : list(range(1,7)) ,'col2' : ['AA','AA','AA','BB','AA','BB']#list('AABCA') ,'col3' : ['2022-01-01','2022-01-01','2022-01-02','2022-01-02','2022-01-03','2022-01-03'] ,'col4' : ['2022-02-01','2022-01-21','2022-01-23','2022-01-12','2022-02-03','2022-01-05'] ,'col5' : [1643673600,1642723200,1642896000,1641945600,1643846400,1641340800] }) df1['col3'] = pd.to_datetime(df1.col3) df1['col4'] = pd.to_datetime(df1.col4) df1
注:直接將代碼放 jupyter 的 cell 跑即可。后文都直接使用
df1
調(diào)用對(duì)應(yīng)的數(shù)據(jù)。
使用 MySQL 構(gòu)建該數(shù)據(jù)集的語法如下:
with t1 as( select 1 as col1, 'AA' as col2, '2022-01-01' as col3, '2022-02-01' as col4, 1643673600 as col5 union all select 2 as col1, 'AA' as col2, '2022-01-01' as col3, '2022-01-21' as col4, 1642723200 as col5 union all select 3 as col1, 'AA' as col2, '2022-01-02' as col3, '2022-01-23' as col4, 1642896000 as col5 union all select 4 as col1, 'BB' as col2, '2022-01-02' as col3, '2022-01-12' as col4, 1641945600 as col5 union all select 5 as col1, 'AA' as col2, '2022-01-03' as col3, '2022-02-03' as col4, 1643846400 as col5 union all select 6 as col1, 'BB' as col2, '2022-01-03' as col3, '2022-01-05' as col4, 1641340800 as col5 ) select * from t1;
注:直接將代碼放 MySQL 代碼運(yùn)行框跑即可。后文跑 SQL 代碼時(shí),默認(rèn)帶上數(shù)據(jù)集(代碼的1~8行),僅展示查詢語句,如第9行。
對(duì)應(yīng)關(guān)系如下:
Python 數(shù)據(jù)集 | MySQL 數(shù)據(jù)集 |
---|---|
df1 | t1 |
date_add()/date_sub()
時(shí)間的加減,在 MySQL 中,使用的是date_add()/date_sub()
來實(shí)現(xiàn),二者可以替換使用,只要對(duì)相加/減的時(shí)間加上負(fù)號(hào)即可(詳見后面例子)。
而在 Pandas 中,可以通過Timedelta()
或DateOffset()
實(shí)現(xiàn),二者有差異,如果是針對(duì)月份和年度計(jì)算差值,只能使用后者;如果是計(jì)算日、時(shí)、分、秒,則二者通用。
時(shí)間范圍對(duì)應(yīng)的語法參數(shù)見下表:
時(shí)間范圍 | date_add()/date_sub() | pandas.Timedelta() | pandas.DateOffset() |
---|---|---|---|
年 | year | - | years |
月 | month | - | months |
日 | day | days | days |
時(shí) | hour | hours | hours |
分 | minute | minutes | minutes |
秒 | second | seconds | seconds |
1、增加1天
MySQL 增加 1 天,可以使用date_add()+1 day
或者用date_sub()-1 day
。
Pandas 中,可以使用 DateFrame 時(shí)間列直接加上pd.Timedelta(days=1)
或者pd.DateOffset(days=1)
。
語言 | Python | MySQL |
---|---|---|
代碼 | 【Python1】 df1.col3 + pd.Timedelta(days=1) 【Python2】 df1.col3 + pd.DateOffset(days=1) | 【MySQL1】 select date_add(t1.col3,interval 1 day) as col3_1 from t1; 【MySQL2】 select date_sub(t1.col3,interval -1 day) as col3_1 from t1; |
結(jié)果 | ![]() | ![]() |
2、減掉1天
語言 | Python | MySQL |
---|---|---|
代碼 | 【Python1】 df1.col3 + pd.Timedelta(days=-1) 【Python2】 df1.col3 + pd.DateOffset(days=-1) | 【MySQL1】 select date_add(t1.col3,interval -1 day) as col3_1 from t1; 【MySQL2】 select date_sub(t1.col3,interval 1 day) as col3_1 from t1; |
結(jié)果 | ![]() | ![]() |
datediff()
計(jì)算時(shí)間的差值,在 MySQL 中,使用datediff(<被減數(shù)>,<減數(shù)>)
(即<被減數(shù)>-<減數(shù)>)實(shí)現(xiàn);而在 Pandas 中,操作相對(duì)簡(jiǎn)單,兩個(gè) Series 相減即可。但是相減之后的數(shù)據(jù)類型是timedelta64[ns]
,如果要用于比較大小,或需要轉(zhuǎn)化為整數(shù),將timedelta64[ns]
的數(shù)值提取出來,提取數(shù)值可以使用其屬性days
并借助apply()
實(shí)現(xiàn),具體代碼邏輯見以下例子。
語言 | Python | MySQL |
---|---|---|
代碼 | (df1.col4-df1.col3).apply(lambda x:x.days) | select datediff(col4,col3) as diff from t1; |
結(jié)果 | ![]() | ![]() |
date_format()
格式設(shè)置,在 MySQL 中,使用date_format()
,在 Python 中,使用strftime()
,二者都是將時(shí)間類型轉(zhuǎn)化為字符串類型。標(biāo)識(shí)符有一點(diǎn)差異,前者的分使用%i
,秒使用%s
,而后者分使用%M
,秒使用%S
。
具體格式參考下表:
時(shí)間范圍(示例) | date_format() | strftime() |
---|---|---|
年,0000~9999 | %Y | %Y |
月,01~12 | %m | %m |
日,01~31 | %d | %d |
時(shí),00~24 | %H | %H |
分,00~59 | %i | %M |
秒,00~59 | %s | %S |
格式化為:年份-月份
MySQL 直接使用date_format(列,"<格式符號(hào)>")
函數(shù)套用即可;而 Python 中,由于strftime('<格式符號(hào)>')
是作用于時(shí)間類型,而df1.col3
是 Series 類型,所以需要使用apply()
來輔助處理每一個(gè)值(如下 Python 代碼)。
語言 | Python | MySQL |
---|---|---|
代碼 | df1.col3.apply(lambda x:x.strftime(‘%Y-%m’)) | select date_format(t1.col3,‘%Y-%m’) as col3_1 from t1; |
結(jié)果 | ![]() | ![]() |
year()/month()/day()/hour()/minute()/second()
取時(shí)間的某一部分(如:年、月、日、時(shí)、分、秒),在 MySQL 中,直接使用對(duì)應(yīng)的函數(shù)作用于字段即可。
在 Python 中,時(shí)間類型的值也有對(duì)應(yīng)的屬性可以獲取到對(duì)應(yīng)的值,同樣地,由于df1.col3
是 Series 類型,所以需要使用apply()
來輔助處理每一個(gè)值(如下 Python 代碼)。
語言 | Python | MySQL |
---|---|---|
代碼 | df_timepart = pd.concat([ df1.col4.apply(lambda x:x.year) ,df1.col4.apply(lambda x:x.month) ,df1.col4.apply(lambda x:x.day) ,df1.col4.apply(lambda x:x.hour) ,df1.col4.apply(lambda x:x.minute) ,df1.col4.apply(lambda x:x.second) ],axis=1 ) df_timepart.columns=[‘year’,‘month’,‘day’,‘hour’,‘minute’,‘second’] df_timepart | select year(col4),month(col4),day(col4),hour(col4),minute(col4),second(col4) from t1; |
結(jié)果 | ![]() | ![]() |
from_unixtime()/unix_timestamp()
使用時(shí)間戳?xí)r,需要特別注意:pandas 采用的是 零時(shí)區(qū)的時(shí)間,MySQL 會(huì)默認(rèn)當(dāng)?shù)貢r(shí)間,北京時(shí)間采用的是東八區(qū),所以北京的時(shí)間會(huì)比零時(shí)區(qū)早8小時(shí),也就是說,同一個(gè)時(shí)間戳,北京時(shí)間會(huì)比零時(shí)區(qū)時(shí)間多8小時(shí),如:1577836800,轉(zhuǎn)化為北京時(shí)間是【2020-01-01 08:00:00】,轉(zhuǎn)化為零時(shí)區(qū)時(shí)間為【2020-01-01 00:00:00】。
1、時(shí)間戳轉(zhuǎn)時(shí)間
時(shí)間戳轉(zhuǎn)時(shí)間,在 MySQL 中,通過from_unixtime()
函數(shù)直接作用于列即可,還可以指定時(shí)間格式,格式化字符參考date_format()
中的表格。
在 Pandas 中,通過to_datetime()
實(shí)現(xiàn),注意需要指定unit
,它根據(jù)時(shí)間戳的精度設(shè)置,常見參數(shù)有:【D,s,ms】,分別對(duì)應(yīng)日數(shù)、秒數(shù)、毫秒數(shù)(相對(duì)1970-01-01 00:00:00的間隔數(shù))。
注意:如果需要轉(zhuǎn)化為東八區(qū),只能通過手動(dòng)添加 8 小時(shí)。
語言 | Python | MySQL |
---|---|---|
代碼 | 【Python 1 默認(rèn)時(shí)區(qū)】 pd.to_datetime(df1.col5, unit=‘s’) 【Python 2 東八時(shí)區(qū)】 pd.to_datetime(df1.col5, unit=‘s’)+pd.Timedelta(hours=8) | select from_unixtime(col5) from t1; |
結(jié)果 | ![]() | ![]() |
2、時(shí)間轉(zhuǎn)時(shí)間戳
時(shí)間轉(zhuǎn)時(shí)間戳,在 MySQL 中,通過unix_timestamp()
函數(shù)直接作用于列即可。
在 Pandas 中,通過apply()+timestamp()
實(shí)現(xiàn),如果需要轉(zhuǎn)化為東八區(qū),先對(duì)時(shí)間做一層tz_localize("Asia/Shanghai")
處理,然后再轉(zhuǎn)化即可,返回的是浮點(diǎn)數(shù)。
注意:這里有一個(gè)小細(xì)節(jié),由于返回的值默認(rèn)是科學(xué)計(jì)數(shù)方式,而我需要查看完整數(shù)字串,而且沒有小數(shù)值,我加了int()
處理。如果使用的時(shí)間精確到毫秒,即存在小數(shù),加int()
處理會(huì)丟失精度,應(yīng)用時(shí)需要結(jié)合自己的實(shí)際情況和需求做處理。
語言 | Python | MySQL |
---|---|---|
代碼 | 【Python 1 默認(rèn)時(shí)區(qū)】 df1.col4.apply(lambda x:int(x.timestamp())) 【Python 2 東八時(shí)區(qū)】 df1.col4.apply(lambda x:int(x.tz_localize(“Asia/Shanghai”).timestamp())) | select unix_timestamp(col4) from t1; |
結(jié)果 | ![]() | ![]() |
三、小結(jié)
1、一個(gè)時(shí)間自定義加減使用Timedelta()
或DateOffset()
;
2、兩個(gè)時(shí)間取差值直接相加減;
3、格式化使用strftime()
;
4、取時(shí)間的指定部分,使用對(duì)應(yīng)的屬性 year
、month
、day
、hour
、minute
、second
;
5、時(shí)間戳和時(shí)間的轉(zhuǎn)化:to_datetime()
、timestamp()
。
到此這篇關(guān)于用Pandas 實(shí)現(xiàn)MySQL日期函數(shù)的效果的文章就介紹到這了,更多相關(guān)Pandas日期函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- MySQL日期格式以及日期函數(shù)舉例詳解
- Mysql日期格式以及內(nèi)置日期函數(shù)用法詳解
- mysql日期函數(shù)TO_DAYS()函數(shù)的詳細(xì)講解
- MySQL學(xué)習(xí)之日期函數(shù)的用法詳解
- MySQL日期函數(shù)與時(shí)間函數(shù)匯總(MySQL 5.X)
- MySQL日期函數(shù)與日期轉(zhuǎn)換格式化函數(shù)大全
- mysql 獲取當(dāng)前日期函數(shù)及時(shí)間格式化參數(shù)詳解
- 深入mysql YEAR() MONTH() DAYOFMONTH()日期函數(shù)的詳解
- mysql From_unixtime及UNIX_TIMESTAMP及DATE_FORMAT日期函數(shù)
- mysql日期函數(shù)用法大全
相關(guān)文章
python數(shù)組中的?k-diff?數(shù)對(duì)例題解析
這篇文章主要介紹了python數(shù)組中的?k-diff?數(shù)對(duì)例題解析,文章根據(jù)題目?jī)?nèi)容對(duì)其進(jìn)行分析以此展開主題內(nèi)容,感興趣的小伙伴可以參考一下下面文章詳情2022-06-06Python代碼覆蓋率統(tǒng)計(jì)工具coverage.py用法詳解
這篇文章主要介紹了Python代碼覆蓋率統(tǒng)計(jì)工具coverage.py用法詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11使用Python的Twisted框架構(gòu)建非阻塞下載程序的實(shí)例教程
Twisted的異步工作模式使其在非阻塞情況下可以擁有較高的性能,這里我們來看一下使用Python的Twisted框架構(gòu)建非阻塞下載程序的實(shí)例教程,包括服務(wù)器端與客戶端的實(shí)踐.2016-05-05Python sqlparse 解析庫的基礎(chǔ)使用過程解析
sqlparse 是一個(gè) Python 庫,是一個(gè)用于 Python 的非驗(yàn)證 SQL 解析器, 用于解析 SQL 語句并提供一個(gè)簡(jiǎn)單的 API 來訪問解析后的 SQL 結(jié)構(gòu),這篇文章主要介紹了Python sqlparse 解析庫的基礎(chǔ)使用,需要的朋友可以參考下2024-08-08python密碼學(xué)RSA算法及秘鑰創(chuàng)建教程
這篇文章主要為大家介紹了python密碼學(xué)RSA算法及秘鑰創(chuàng)建教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05Python通過調(diào)用mysql存儲(chǔ)過程實(shí)現(xiàn)更新數(shù)據(jù)功能示例
這篇文章主要介紹了Python通過調(diào)用mysql存儲(chǔ)過程實(shí)現(xiàn)更新數(shù)據(jù)功能,結(jié)合實(shí)例形式分析了Python調(diào)用mysql存儲(chǔ)過程實(shí)現(xiàn)更新數(shù)據(jù)的具體步驟與相關(guān)操作技巧,需要的朋友可以參考下2018-04-04利用python繪制數(shù)據(jù)曲線圖的實(shí)現(xiàn)
這篇文章主要介紹了利用python繪制數(shù)據(jù)曲線圖的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04