Pandas数据分析06——高级筛选和查询

 参考书目:《深入浅出Pandas:利用Python进行数据处理与分析》


pandas的数据框可以进行各种自带方法的筛选和查询,可以使用各种逻辑个条件去找出符合要求的数据。

首先读取演示数据集

import numpy as np
import pandas as pd 
import datetime
data = 'https://www.gairuo.com/file/data/dataset/team.xlsx'
df = pd.read_excel(data) 

条件判断返回(布尔值)

df.Q1>90
df.index==1
df.loc[:,'Q1':'Q4']>60
~(df.Q1<60)&(df['team']=='C')#Q1成绩不小于60,且是c组


逻辑筛选数据

df[df['Q1'] == 8] # Q1 等于8
df[~(df['Q1'] == 8)] # 不等于8
df[df.name == 'Ben'] # 姓名为Ben
df[df.Q1 > df.Q2]
#loc
df.loc[df['Q1']==8]
df.loc[df['Q1'] > 90, 'Q1':]  # Q1 大于90,显示Q1后边的所有列
df.loc[(df.Q1 > 80) & (df.Q2 < 15)] # and 关系
df.loc[(df.Q1 > 90) | (df.Q2 < 90)] # or 关系
df[(df.loc[:,['Q1','Q2']]>80).all(1)]#Q1和Q2都大于80分
df[(df.loc[:,['Q1','Q2']]>80).any(1)]#Q1和Q2至少一个大于80分


 函数筛选

df.Q1[lambda s:max(s.index)]##最大索引的值 索引为99的人的Q1分数
max(df.Q1.index)  #计算索引最大值
df.Q1[max(df.Q1.index)]  #结果一样
df[lambda df: df['Q1'] == 8] # Q1为8的
df.loc[lambda df: df.Q1 == 8, 'Q1':'Q2'] # Q1为8的, 显示 Q1 Q2
# 选择字段时尽量使用字典法,属性法在条件表达式时一些情况可能有 bug

df.loc[:, lambda df: df.columns.str.len()==4] # 真假组成的序列
df.loc[:, lambda df: [i for i in df.columns if 'Q' in i]] # 列名列表
df.iloc[:3, lambda df: df.columns.str.len()==2] # 真假组成的序列
df[df.Q1.eq(60)]#相对于df[df.Q1==60]
df.eq() # 等于相等 ==
df.ne() # 不等于 !=
df.le() # 小于等于 >=
df.lt() # 小于 <
df.ge() # 大于等于 >=
df.gt() # 大于 >
# 都支持  axis{0 or ‘index’, 1 or ‘columns’}, default ‘columns’
df[df.Q1.ne(89)] # Q1 不等于8
df.loc[df.Q1.gt(90) & df.Q2.lt(90)] # and 关系 Q1>90 和Q2<90
df.loc[df[['Q1','Q3']].gt(60).all(1)] #相当于 df.loc[(df.Q1 > 60) & (df.Q3 > 60)] 
# isin
df[df.team.isin(['A','B'])] ##相当于df[(df.team=='A')|(df.team=='B')]
df[df.isin({'team': ['C', 'D'], 'Q1':[36,93]})] # 复杂查询,其他值为 NaN

查询query (字符串表达式)

df.query('Q1 > Q2 > 90') # 直接写类型 sql where 语句
df.query('Q1 + Q2 > 180')
df.query('Q1 == Q2')
df.query('(Q1<50) & (Q2>40) and (Q3>90)')
df.query('Q1 > Q2 > Q3 > Q4')

df.query('team != "C"')
df.query('team in ["A","B"]')
df.query('team not in ("E","A","B")')
df.query('team == ["A","B"]')
df.query('team != ["A","B"]')
df.query('name.str.contains("am")') # 包含 am 字符
# 对于名称中带有空格的列,可以使用反引号引起来
df.query('B == `team name`')
# 支持传入变量,如:大于平均分40分的
a = df.Q1.mean()
df.query('Q1 > @a+40')
df.query('Q1 > `Q2`+@a')

# df.eval() 用法与 df.query 类似
df[df.eval("Q1 > 90 > Q3 > 10")]
df[df.eval("Q1 > `Q2`+@a")]

筛选 filter

df.filter(items=['Q1', 'Q2']) # 选择两列
df.filter(regex='Q', axis=1) # 列名包含Q的
df.filter(regex='e$', axis=1) # 正则,以 e 结尾的
df.filter(regex='1$', axis=0) # 正则, 索引名1结尾的
df.filter(like='2', axis=0) # 索引中有2的
# 索引中2开头列名有Q的
df.filter(regex='^2', axis=0).filter(like='Q', axis=1)

数据类型筛选

df.select_dtypes(include=['float64']) # 选择 float64 型数据
df.select_dtypes(include='bool')
df.select_dtypes(include=['number']) # 只取数字型
df.select_dtypes(exclude=['int64']) # 排除 int 类型
df.select_dtypes(exclude=['datetime64'])

高级过滤(where 和 mask) 替换

df=df.select_dtypes(include=['number'])#先只取数字
##where是返回布尔值为真的位置的值,为假返回nan,形状与原来一样
s.where(s > 90) # 不符合条件的为 NaN
s.where(s > 90, 0) # 可以替换不符合条件的值,为 0

df.where(df>70)
df.where(lambda d:d.Q1>50)
df.Q1.where(pd.Series([True]*3))  #只取前三个
df.where(df>60,'不及格')#将nan替换为不及格
#给定算子
c=df%2==0
df.where(~c,-(df-20))#为偶数时返回原来的值减去20的相反数
# np.where, 可以对满足条件的值也进行替换
np.where(s>80, True, False)
np.where(df>=60, '合格', '不合格')
df.where(df==99999,np.where(df>60,'合格', '不合格'))##让df.where中条件为假,应用np.where
#例子
df.assign(avg=df.mean(1)).assign(及格=lambda d:np.where (d.avg>60,'是','否')) #计算平均成绩,判断是否及格
#相当于
#m=df.mean(1)
#m=m.where(m>60,'不及格')
#m.where(m=='不及格','及格')
#上面两句改为m.where(m==99999,np.where(m>60,'合格', '不合格'))
#还可以用apply函数

###mask用法和where基本相同,就是满足条件的位置返回Nan
df.mask(df > 90) # 符合条件的为 NaN
df.mask(df > 90, 0) # 符合条件的为 0
df.Q1.mask(df.Q1>80,'优秀')
# 例:能被3整除的显示,不能的显示相反数
m = df.loc[:,'Q1':'Q4'] % 3 == 0
df.loc[:,'Q1':'Q4'].where(m, -df.loc[:,'Q1':'Q4'])

查找lookup

# 行列相同数量,返回一个 array
df.lookup([1,3,4], ['Q1','Q2','Q3'])  # array([36, 96, 61])
df.lookup([1], ['Q1']) # array([36]) #相当于df.loc[1,'Q1']

猜你喜欢

转载自blog.csdn.net/weixin_46277779/article/details/126104846