五花八门的 Pandas 筛选数据
今天继续带来 Pandas 的花样取数技巧,本文中重点介绍的方法:
表达式取数 query、evel filter where、mask
一、模拟数据
下面是完全模拟的一份数据,包含:姓名、性别、年龄、数学、语文、总分、地址共 7 个字段信息。
import pandas as pd
import numpy as np
df = pd.DataFrame({
"name":['小明','小王','张菲','关宇','孙小小','王建国','刘蓓'],
"sex":['男','女','女','男','女','男','女'],
"age":[20,23,18,21,25,21,24],
"math":[120,130,118,120,102,140,134],
"chinese":[100,130,140,120,149,111,118],
"score":[590,600,550,620,610,580,634],
"address":["广东省深圳市南山区",
"北京市海淀区",
"湖南省长沙市雨花区",
"北京市东城区",
"广东省广州市白云区",
"湖北省武汉市江夏区",
"广东省深圳市龙华区"
]
})
df
![](https://filescdn.proginn.com/be93e8902056bb9e25bd6adac73e34ad/eb26a31d928463f9c88cb56933213a38.webp)
下面开始详细介绍 5 种取数方法:
表达式取数 query()取数 eval()取数 filter()取数 where/mask取数
二、表达式取数
表达式取数指的是通过表达式来指定一个或者多个筛选条件来取数。
1、指定一个数学表达式
# 1、数学表达式
df[df['math'] > 125]
![](https://filescdn.proginn.com/f8030811781d2ccca7f11d5ba1e12104/93ece1a14707c859647b9f3cebf1e319.webp)
2、取反操作
取反操作是通过符号~来实现的
# 2、取反操作
df[~(df['sex'] == '男')] # 取出不是男生的数据
3、指定某个属性的值为具体的数据
# 3、指定具体数据
df[df.sex == '男'] # 等同于 df[df['sex'] == '男']
![](https://filescdn.proginn.com/dd8d97b2b24bf64280ee3027c089fb41/623b4f89c23b9b3d37b93fe53071b019.webp)
4、不等式表达式
# 4、比较表达式
df[df['math'] > df['chinese']]
![](https://filescdn.proginn.com/708e8a8b97b752279102cc022bfb1ef5/065cd05e367784be01c38fc162fdd32d.webp)
5、逻辑运算符
# 5、逻辑运算符
df[(df['math'] > 120) & (df['chinese'] < 140)]
![](https://filescdn.proginn.com/1b132186c4efda7571de23febc123e52/3c519fc748dff3a5b080784c15ef4cec.webp)
三、query()函数
3.1 使用说明
![](https://filescdn.proginn.com/bd1aa10ccf3c34ef847ac0d4c269ca2b/a3943c4112c4f3ff03d2699438ca81b3.webp)
⚠️在使用的时候需要注意的是:如果我们列属性中存在空格,我们需要使用反引号将其括起来再进行使用。
3.2 使用案例
1、使用数值型表达式
df.query('math > chinese > 110')
![](https://filescdn.proginn.com/cc2dabf31d745149fe1a0fb734952e65/1b4003d61bd3a7a7d7e62d4c3e30d62b.webp)
df.query('math + chinese > 255')
![](https://filescdn.proginn.com/add4645ddd76acea4c6af961c57aae23/b08f536f5c3d3c2ecccb45dc6e74b181.webp)
df.query('math == chinese')
![](https://filescdn.proginn.com/b7c8f294a736750d46940a8565fe43e7/d76496dd5f403bcfd5cdb50f6a40d935.webp)
df.query('math == chinese > 120')
![](https://filescdn.proginn.com/7ac1e8487a46412a4161c6b17d49b2fe/30e1d58bc44420bad2c9a61dde4f6661.webp)
df.query('(math > 110) and (chinese < 135)') # 两个不等式
![](https://filescdn.proginn.com/ed5ddfcd758a60cedd44606eb8717086/943e44ef81ec4882c95422ff6968a20d.webp)
2、使用字符型表达式
df.query('sex != "女"') # 不等于女,就是全部男
![](https://filescdn.proginn.com/027ea8ab53063311a6794b6d60b438b8/6877822792ee249893a12022e983ee54.webp)
df.query('sex not in ("女")') # 不在女中就是男
![](https://filescdn.proginn.com/339e77fef7d10611edc4898b93ff302c/c0a960595b596adc9c12564369bd4e86.webp)
df.query('sex in ("男","女")') # 性别在男女中就是全部人
![](https://filescdn.proginn.com/ccbf11f067848fbfa0783248ea0b9649/2b4c893dc5f8c8a350656b4b3dcdda91.webp)
3、传入变量;变量在使用的时候需要在前面加上@
# 设置变量
a = df.math.mean()
a
df.query('math > @a + 10')
![](https://filescdn.proginn.com/f9f9557be27d7e2fe8ca33d3ffe80139/3f64033923bc8529ec42f2550fc32bd7.webp)
df.query('math < (`chinese` + @a) / 2')
![](https://filescdn.proginn.com/6565799d5a45c3710740a6e766aaee39/fc0c70a96b5da47effd3e5a9aca2f50f.webp)
四、eval()函数
eval函数的使用方法和query函数是相同的
1、使用数值型表达式
# 1、数值型表达式
df.eval('math > 125') # 得到的是bool表达式
![](https://filescdn.proginn.com/34e5b6edc35ba8ca63056a69766afee5/9c1e75ab8d9e17c83cc1e1a736064092.webp)
df[df.eval('math > 125')]
![](https://filescdn.proginn.com/ca0369ba570a58e56bfbf675bc433cec/c65847ddf40ab14509e5aa87841cf150.webp)
df[df.eval('math > 125 and chinese < 130')]
![](https://filescdn.proginn.com/7fbc4637a89729846195babd23c871d6/009e00d9202905cac19a83e53a25cbcf.webp)
2、字符型表达式
# 2、字符型表达式
df[df.eval('sex in ("男")')]
![](https://filescdn.proginn.com/a4ca9f5f721c709ced01f640c7e89d07/afdd931b8fde29ad2bba0792e0d6e286.webp)
3、使用变量
# 3、使用变量
b = df.chinese.mean() # 求均值
df[df.eval('math < @b+5')]
![](https://filescdn.proginn.com/6031f5e947b1d12506f76bf18a57db61/085b87686a63473973be07c84a4048e4.webp)
五、filter函数
我们使用filter可以对列名或者行名进行筛选,使用方法:
直接指定 正则指定 模糊指定
其中axis=1指定列名;axis=0指定索引
5.1 使用说明
![](https://filescdn.proginn.com/90dd4aa61fd5ea48e3ddfa9ec761c0ca/62de1b617c2a7a09f0a6c8c4739889af.webp)
5.2 使用案例
1、直接指定属性名
df.filter(items=["chinese","score"]) # 列名操作
![](https://filescdn.proginn.com/d518c9f0da7b69d748f9e9be1deabcbd/e19d9de241ac0838c7eac403d86c6c92.webp)
直接指定行索引
df.filter(items=[2,4],axis=0) # 行筛选
![](https://filescdn.proginn.com/7966e38cc0f3c6d930a37fcc415a9491/8ffabd6571f9cb5df3c3f44cccd2e44b.webp)
2、通过正则指定
df.filter(regex='a',axis=1) # 列名中包含
![](https://filescdn.proginn.com/c90d2db9c6be0dcb40a7981c4ec530c0/ede2d644a95aa74526a762ec310a4714.webp)
df.filter(regex='^s',axis=1) # 列名以s开始
![](https://filescdn.proginn.com/8c822c3a448bae262a5a16b56adeab5e/406625447dc220a74e8c1a7ddd476e45.webp)
df.filter(regex='e$',axis=1) # 列名以e结束
![](https://filescdn.proginn.com/e1c17026d89222052e6ef23718cf1a9a/c24a181f8fdd18c29749ba1110fed02e.webp)
df.filter(regex='3$',axis=0) # 行索引包含3
![](https://filescdn.proginn.com/cbfb91d16716c43a908d8b5aa66105c4/1bbb2484f4f88796c757876ab67643cf.webp)
3、模糊指定
df.filter(like='s',axis=1) # 列名中包含s
![](https://filescdn.proginn.com/4b3f7078a0f06bb8f20ae12de863f483/9c53b9ef267f5cc3344592d900f2aa71.webp)
df.filter(like='2',axis=0) # 行索引包含2
![](https://filescdn.proginn.com/967209b490447ca229f3559d1cb554b8/37ebde1554ab216a221c0e4076b2e1d8.webp)
# 同时指定列名和索引
df.filter(regex='^a',axis=1).filter(like='2',axis=0)
![](https://filescdn.proginn.com/03888e866275bfa66488c340e0629c06/cde23955a512c643d457b782336577c1.webp)
六、where和mask函数
where和mask函数是一对相反的函数,取出来的结果刚好是相反的:
where:取出满足要求的数据,不满足的显示为NaN mask:取出不满足要求的数据,满足的显示为NaN
两种方法都可以将将NaN值设置我们指定的数据
6.1 where使用
s = df["score"]
s
![](https://filescdn.proginn.com/dd006b9d4ccd720f00b31627cba875f3/ac2952baa098003cd842ef2a1ac9bf53.webp)
# where:满足条件的直接显示,不满足的显示为NaN
s.where(s>=600)
![](https://filescdn.proginn.com/65a7393bbea3a1e88087a6349bc83135/334f6173fc6f7a211585f278f263ab53.webp)
我们可以给不满足要求的数据进行赋值:
# 我们可以给不满足的进行赋值
s.where(s>=610,600) # 不满足条件的赋值为600
![](https://filescdn.proginn.com/70975b93abc6e8dd29924799cbd87caa/3c160b64cf195fb6ff7e49823679b76a.webp)
看看两组结果的对比:
![](https://filescdn.proginn.com/e6a64e3601e27fa0d3309c28ae357e39/709e060692175ec50cf436fcbf5fd213.webp)
where函数还可以指定多个条件:
# 符合条件的返回True,不符合的返回False
df.where((df.sex=='男') & (df.math > 125))
![](https://filescdn.proginn.com/8e2a19a229c6321a674aca8ed4dbe7b5/feacc1aa884c544f144a347bf456e085.webp)
选出我们想要的数据:
df[(df.where((df.sex=='男') & (df.math > 125)) == df).name]
# df[(df.where((df.sex=='男') & (df.math > 125)) == df).sex] 效果相同
![](https://filescdn.proginn.com/ad62bf2f53402a29acb30e284e407137/bcf00fe49b5703478008dfcc40486c2f.webp)
6.2 mask函数
mask函数获取到的结果和where是相反的
s.mask(s>=600) # 和where相反:返回的都是小于600的数据
![](https://filescdn.proginn.com/2a22a494e2f5bd039dae551c5c9552f4/2ec264580234f03bafe9c676972c7d36.webp)
s.mask(s>=610, 600) # 不满足条件的赋值为600
![](https://filescdn.proginn.com/c5d41ce89852a17db8b1f6b49bc5efbe/98ff6f31d0583a8a26876f8be49a33fb.webp)
mask函数接受多个条件:
# 取值和where相反
df[(df.mask((df.sex=='男') & (df.math > 125)) == df).sex]
![](https://filescdn.proginn.com/99ef82009edf35f1cc6901b0a11d87ea/5a0f68afd75324f52c8b3210963bac6d.webp)
七、总结
Pandas中取数的方法真的五花八门,太多技巧可以获取到我们想要的数据,有时候不同的方式也可以得到相同的数据。本文中着重介绍的通过表达式和5个函数来取数,下篇文章中将会重点讲解3对函数筛选数据的方法。
评论