關于pandas.DataFrame的類SQL操作
前言
pandas的DataFrame是類似于一張表的結構,但是并沒有像數據庫表那樣的SQL操作。
雖然如此,它依然可以使用python語言的風格實現SQL中的所有操作。
where、limit、sort by和order by
首先我們講一些常用的最基本的SQL操作。
首先創(chuàng)建一個DataFrame。
# 首先構建一個df,用于執(zhí)行相關操作 import numpy as np import pandas as pd index = pd.date_range('20191201',periods=30) df = pd.DataFrame(np.random.randn(30,7),index=index,columns=['Sun','Mon','Tues','Wed','Thur','Fri','Set'])
# 查詢df表中,12月前五天工作日的所有數據 # sql:select Mon, Tues, Wed, Thur, Fri from df limit 5; # pandas DataFrame方式 df[['Mon','Tues','Wed','Thur','Fri']].head() # 默認取前5 ''' Mon Tues Wed Thur Fri 2019-12-01 0.804610 0.368983 -0.601083 -1.245074 -0.484798 2019-12-02 1.260151 -1.409303 -0.634084 -1.036428 2.090475 2019-12-03 -1.728074 0.906895 0.015032 -1.311078 -1.329503 2019-12-04 -0.489368 -1.285120 -0.115737 0.138407 -1.360219 2019-12-05 -0.686239 -0.715345 -1.216979 -0.110652 -0.716998 '''
# 使用where條件,過濾大于Mon大于1的行,并且是工作日的列,并按照Mon降序排序,去除前五行 # SQL:select Mon,Tues,Wed,Thur,Fri from df where Mon > 0 order by Mon desc limit 5; df[df['Mon'] > 1][['Mon','Tues','Wed','Thur','Fri']].sort_values('Mon',ascending=False).head() ''' Mon Tues Wed Thur Fri 2019-12-24 3.428393 -0.117491 -1.050417 0.013496 0.744957 2019-12-22 2.264095 0.580407 1.992808 0.277741 0.691637 2019-12-18 1.919169 1.108332 1.135021 0.468483 0.718493 2019-12-29 1.442418 -0.555409 1.483127 -0.322987 0.480643 2019-12-11 1.304989 0.289543 0.591583 -0.420857 -0.407957 '''
where多條件查詢
and條件
# where中有多個條件,要注意兩個條件如果是and用&,且條件要用小括號包裹一下 # select * from df where Sun > 0 and Mon < 0 order by Sun desc; df[(df['Sun'] > 0) & (df['Mon'] < 0)].sort_values('Sun',ascending=False) ''' Sun Mon Tues Wed Thur Fri Set 2019-12-04 2.196878 -0.489368 -1.285120 -0.115737 0.138407 -1.360219 0.093402 2019-12-25 1.245318 -2.336478 0.166749 0.665577 -1.740905 -0.719664 0.011632 2019-12-21 0.984376 -0.395367 0.859675 0.035257 -0.326325 2.049639 -0.104049 2019-12-20 0.916271 -2.208159 0.680670 -1.392549 0.310099 -0.655601 1.008948 2019-12-08 0.680180 -0.682509 0.263885 0.270527 0.428712 -0.566694 -0.426841 2019-12-03 0.552253 -1.728074 0.906895 0.015032 -1.311078 -1.329503 -1.179729 '''
or條件
# or條件,在DataFrame中使用的是按位或符號:| # sql: select * from df where Sun > 1 or Set > 1 order by Sun; df[(df['Sun'] > 1) | (df['Set'] >1)].sort_values('Sun',ascending=False) ''' Sun Mon Tues Wed Thur Fri Set 2019-12-19 2.200183 1.126807 1.650156 0.165897 1.262572 1.083929 2.151953 2019-12-04 2.196878 -0.489368 -1.285120 -0.115737 0.138407 -1.360219 0.093402 2019-12-25 1.245318 -2.336478 0.166749 0.665577 -1.740905 -0.719664 0.011632 2019-12-07 1.189126 0.115880 0.237899 -0.265956 0.882976 -0.932736 0.385194 2019-12-20 0.916271 -2.208159 0.680670 -1.392549 0.310099 -0.655601 1.008948 2019-12-14 0.063325 0.553131 0.221180 0.265838 0.260798 1.100413 1.112681 '''
空值查詢
在DataFrame中判斷空值使用isna()和notna()兩個方法
# 先構造一個帶空置的DataFrame dfna = pd.DataFrame({ "one":pd.Series([1,2,3,np.NaN,5,6]), "two":pd.Series([1,2,np.NaN,5,6,np.NaN]), "three":pd.Series([np.NaN,5,6,np.NaN,7,8]), }) # 查詢three列不是空值的全部數據 # SQL:select * from dfna where three is not null; dfna[dfna['three'].notna()] ''' one two three 1 2.0 2.0 5.0 2 3.0 NaN 6.0 4 5.0 6.0 7.0 5 6.0 NaN 8.0 ''' # 查詢表中three是空值的全部列 # SQL:select * from dfna where three is null; dfna[dfna['three'].isna()] ''' one two three 0 1.0 1.0 NaN 3 NaN 5.0 NaN '''
分組
- 先創(chuàng)建一個表,用于分組測試用
- DataFrame的分組與SQL最大的不同時,SQL只能對分組列進行聚合,但是DataFrame不止可以對分組列聚合,其他列只要可以進行聚合操作都可以進行聚合
- DataFrame可以對多列進行不同類型的聚合運算,需要使用agg函數并傳入一個dict對象
- 可以使用多列作為條件進行分組
# 人員基本信息表 fdf = pd.DataFrame({ "name":pd.Series(['Zero','Zoey','Bella','Kat','Sid']), "age":pd.Series([23,24,23,26,23]), "gender":pd.Series(['male','female','female','female','male']), "address":pd.Series(['jinan','nanjing','qingdao','dongjing','dongjing']), "salary":pd.Series([8888.8,6666.6,1234.5,2345.6,5678.9]) }) # 按性別分組,求出男女的平均工資 fdf.groupby('gender').mean()['salary'] ''' gender female 3415.566667 male 7283.850000 Name: salary, dtype: float64 ''' #求出男女人數 fdf.groupby('gender').size() ''' gender female 3 male 2 dtype: int64 ''' # 分組后對不同列進行不同類型的聚合 # 按照gender進行分組,對salary求平均值,對age求總數 fdf.groupby('gender').agg({'salary':np.mean, 'age':np.size}) ''' salary age gender female 3415.566667 3 male 7283.850000 2 '''
JOIN
- join跟sql一樣支持左外、右外,全外和內連接四種連接
- 先創(chuàng)建兩個df用于進行join操作
- DataFrame可以使用join()和merge()兩種函數進行join操作,這里使用merge進行測試
# 創(chuàng)建兩個待join的表 df1 = pd.DataFrame({ "key":['A','B','C','D','E'], "val":np.random.randn(5) }) df2 = pd.DataFrame({ "key":['C','B','F','H','D'], "val":pd.Series(np.random.randn(5)) }) # 根據key列進行join操作,內連接 df1.merge(df2,on='key') # 右外連接 df1.merge(df2, on='key', how='right') # 左外連接 df1.merge(df2, on='key', how='left') # 全外連接 df2.merge(df2, on='key', how='outer') # 全外,上面的全外不是真的全外,要用這種方式才能做到全外連接 pd.merge(df1, df2, on='key',how='outer')
Union
- union操作使用concat()進行完成
- concat是pandas的函數筆試dataframe的函數
- concat接受一個數組作為入參,所以在進行union的時候,需要將多個df放入一個數組中
# 合并兩個DataFrame并去重 pd.concat([df1, df2]).drop_duplicates() ''' key val 0 A -0.309694 1 B 1.455732 2 C 0.436620 3 D 0.970044 4 E -0.689002 0 C 0.405784 1 B -0.522076 2 F 0.147848 3 H -1.609153 4 D 1.205187 '''
添加一列
df1.assign(score=np.random.randint(60,100,size=5)) ''' key val score 0 A -0.309694 80 1 B 1.455732 92 2 C 0.436620 92 3 D 0.970044 95 4 E -0.689002 89 '''
top N 相關函數
- 在DataFrame中有直接求top N的函數
- nlargest(n,col)求col列中前n大的行
- nsmallest(n,col)求col列中前n小的行
df.nlargest(3,columns='Sun') df.nsmallest(3,columns='Sun') # 這里也是top N,但是是基于分組的top N # assign是添加一列 # 添加的列叫rn # sort_values是對salary進行排序 # groupby是對gender進行分組 # cumcount是按照上面給定的順序從0開始給一個順序號 fdf.assign( rn=fdf.sort_values(['salary'], ascending=False) .groupby(['gender']) .cumcount()+1 ).sort_values('name') # 下面的結果說明了男女中工資從低到高的排序順序 ''' name age gender address salary rn 2 Bella 23 female qingdao 1234.5 3 3 Kat 26 female dongjing 2345.6 2 4 Sid 23 male dongjing 5678.9 2 0 Zero 23 male jinan 8888.8 1 1 Zoey 24 female nanjing 6666.6 1 '''
總結
pandas是一個非常強大的科學計算庫,DataFrame的功能也遠不止這么簡單。
這里只是總結了一些常用的類似于SQL的操作方法。
如果需要更加復雜的功能可以查看DataFrame的官方文檔。
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Python pyinotify日志監(jiān)控系統(tǒng)處理日志的方法
這篇文章主要介紹了Python pyinotify日志監(jiān)控系統(tǒng)處理日志的方法,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-03-03淺談Tensorflow 動態(tài)雙向RNN的輸出問題
今天小編就為大家分享一篇淺談Tensorflow 動態(tài)雙向RNN的輸出問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-01-01python 內置函數-range()+zip()+sorted()+map()+reduce()+filte
這篇文章主要介紹了python 內置函數-range()+zip()+sorted()+map()+reduce()+filter(),想具體了解函數具體用法的小伙伴可以參考一下下面的介紹,希望對你有所幫助2021-12-12