关于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的官方文档。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Flask框架debug与配置项的开启与设置详解

    Flask框架debug与配置项的开启与设置详解

    这篇文章主要介绍了Flask框架debug与配置项的开启与设置,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-09-09
  • Python pyinotify日志监控系统处理日志的方法

    Python pyinotify日志监控系统处理日志的方法

    这篇文章主要介绍了Python pyinotify日志监控系统处理日志的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-03-03
  • 浅谈Tensorflow 动态双向RNN的输出问题

    浅谈Tensorflow 动态双向RNN的输出问题

    今天小编就为大家分享一篇浅谈Tensorflow 动态双向RNN的输出问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-01-01
  • 基于python-pptx库中文文档及使用详解

    基于python-pptx库中文文档及使用详解

    今天小编就为大家分享一篇基于python-pptx库中文文档及使用详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-02-02
  • rhythmbox中文名乱码问题解决方法

    rhythmbox中文名乱码问题解决方法

    在使用rhythmbox过程中,出现了,如果是中文名则会出现乱码,下面的方法即可解决
    2008-09-09
  • 使用python将csv数据导入mysql数据库

    使用python将csv数据导入mysql数据库

    这篇文章主要为大家详细介绍了如何使用python将csv数据导入mysql数据库,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-05-05
  • 一篇文章彻底搞懂python正则表达式

    一篇文章彻底搞懂python正则表达式

    正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配,Python 自1.5版本起增加了re模块,这篇文章主要给大家介绍了如何通过一篇文章彻底搞懂python正则表达式的相关资料,需要的朋友可以参考下
    2021-09-09
  • python 内置函数-range()+zip()+sorted()+map()+reduce()+filter()

    python 内置函数-range()+zip()+sorted()+map()+reduce()+filte

    这篇文章主要介绍了python 内置函数-range()+zip()+sorted()+map()+reduce()+filter(),想具体了解函数具体用法的小伙伴可以参考一下下面的介绍,希望对你有所帮助
    2021-12-12
  • Python实现将多张图片合成视频并加入背景音乐

    Python实现将多张图片合成视频并加入背景音乐

    这篇文章主要为大家介绍了如何利用Python实现将多张图片合成mp4视频,并加入背景音乐。文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2022-04-04
  • 如何使用python实现模拟鼠标点击

    如何使用python实现模拟鼠标点击

    这篇文章主要介绍了如何使用python实现模拟鼠标点击,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01

最新评论