关于pandas.DataFrame的类SQL操作
更新时间:2023年08月18日 15:39:00 作者:iFence
这篇文章主要介绍了关于pandas.DataFrame的类SQL操作方式,具有很好的参考价值,希望对大家有所帮助,
前言
pandas的DataFrame是类似于一张表的结构,但是并没有像数据库表那样的SQL操作。
虽然如此,它依然可以使用python语言的风格实现SQL中的所有操作。
where、limit、sort by和order by
首先我们讲一些常用的最基本的SQL操作。
首先创建一个DataFrame。
# 首先构建一个df,用于执行相关操作 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 '''
分组
- 先创建一个表,用于分组测试用
- 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一样支持左外、右外,全外和内连接四种连接
- 先创建两个df用于进行join操作
- DataFrame可以使用join()和merge()两种函数进行join操作,这里使用merge进行测试
# 创建两个待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的官方文档。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
最新评论