Pandas筛选之query

1
2
3
4
5
6
import os
import re

import numpy as np
import pandas as pd
from heapq import nlargest,nsmallest

下载数据

1
2
3
url = "http://www.51chanlun.com/hot.html"
df = pd.read_html(url, header=0, encoding="utf-8")[3]
df.head(2)
概念类别 新高个股数 板块是否强势 板块强弱指标 强弱变化% 近10日分 中10日分 远10日分 1110 1109 ... 0412 0411 0410 0407 0406 0405 0404 0403 0331 0330
0 汽车类 7 0 4.2240 -12.66 26 27 23 001=5 003=5 ... 015=2 015=1 N N N N N 013=3 018=1 001=5
1 工业机械 9 0 4.5852 -3.58 20 20 20 002=4 018=1 ... 006=7 009=3 006=3 013=3 004=7 008=3 008=3 015=3 004=5 014=1

2 rows × 159 columns

过滤需要的数据列

1
2
3
4
5
df = df.filter(
["概念类别", "新高个股数", "板块是否强势", "板块强弱指标"])

df.columns = ['type','num','strong','index']
df.sample(8)
type num strong index
32 多元金融 0 0 2.1333
39 电信运营 0 1 4.0000
33 家居用品 2 1 4.5714
24 交通设施 2 0 3.1395
4 半导体 10 0 5.1925
19 文教休闲 2 0 3.5660
49 通信设备 4 0 4.9091
51 酒店餐饮 0 0 1.0000

Query 函数筛选

  • query : 查询的意思

语法:df.query(expr,inplace = False,** kwargs) # 使用布尔表达式查询帧的列
参数:

  • expr:str要评估的查询字符串。你可以在环境中引用变量,在它们前面添加一个‘@’字符 。@a + b
  • inplace=False:是否修改数据或返回副本
  • kwargs:dict关键字参数
  • 返回:DataFrame

注意:

  • 默认修改Python语法’&’/‘and’和’|’/‘or’位运算符优先级高于布尔表达式,不同于Python

  • 关键字参数parser=’python’执行Python评估。

  • engine=’python’ 用Python本身作为后端来传递评估表达式。不建议效率低。

  • 默认实例df.index和 df.columns属性 DataFrame放在查询命名空间中,

  • 这允许您将框架的索引和列视为框架中的列。标识符index用于帧索引;

  • 您还可以使用索引的名称在查询中标识它。

性能:

  • 涉及NumPy数组或Pandas DataFrames的复合表达式都会导致隐式创建临时数组
  • eval/query用在数据(df.values.nbytes>1万)性能提升明显;传统方法在小数组时运行得更快;
  • eval/query好处主要时节省内存,以及有时候简洁得语法
  • 可用指定不同解析器和引擎来运行这些查询;参见”Enhancing Performance” 。

条件是一个字符串的形式

1
df.query("num >= 10")  # 等价于  df[df['num']>=10]
type num strong index
3 化工 16 1 4.5868
4 半导体 10 0 5.1925
13 元器件 12 0 5.7186
1
df.query("type.str.contains('电')  & num >= 5")
type num strong index
2 电气设备 6 0 4.1577
9 家用电器 6 0 4.4304

@ 符号来标记本地变量

1
2
3
4
5
# 设定条件
Bmean = df["num"].mean() + 3

# 列 num 的值 `>` 条件Beam
df.query("num>@Bmean")
type num strong index
0 汽车类 7 0 4.2240
1 工业机械 9 0 4.5852
2 电气设备 6 0 4.1577
3 化工 16 1 4.5868
4 半导体 10 0 5.1925
5 软件服务 7 0 4.5000
9 家用电器 6 0 4.4304
13 元器件 12 0 5.7186
30 医药 8 0 5.3627
1
2
3
4
# 或者:
Beam = df['num'] > df['num'].mean() + 3
df.query("@Beam") # 同上等价

type num strong index
0 汽车类 7 0 4.2240
1 工业机械 9 0 4.5852
2 电气设备 6 0 4.1577
3 化工 16 1 4.5868
4 半导体 10 0 5.1925
5 软件服务 7 0 4.5000
9 家用电器 6 0 4.4304
13 元器件 12 0 5.7186
30 医药 8 0 5.3627

eval 的应用

1
2
3
# num 列的值 > 10
tj = df.eval("num >10 ")
df.query("@tj")
type num strong index
3 化工 16 1 4.5868
13 元器件 12 0 5.7186
1
2
3
# num 列的值 > 10 并且 strong == 1
tj = df.eval("(num >=10) & (strong ==1)")
df.query("@tj")
type num strong index
3 化工 16 1 4.5868
1
2
3
# NUM 、Index列的值均大于其平均值
tj = df.eval('num > num.mean() & index > index.mean()')
df.query('@tj')
type num strong index
0 汽车类 7 0 4.2240
1 工业机械 9 0 4.5852
2 电气设备 6 0 4.1577
3 化工 16 1 4.5868
4 半导体 10 0 5.1925
5 软件服务 7 0 4.5000
7 供气供热 5 1 5.0233
9 家用电器 6 0 4.4304
13 元器件 12 0 5.7186
16 通用机械 3 0 4.6172
18 煤炭 5 1 5.7273
29 医疗保健 5 0 5.0788
30 医药 8 0 5.3627
49 通信设备 4 0 4.9091
1
2
3
4
# num列的值排名其前3 ,index列值大于其平均值
nlg = nlargest(3,df['num'])
tj = df.eval('num in @nlg & index > index.mean()')
df.query('@tj')
type num strong index
3 化工 16 1 4.5868
4 半导体 10 0 5.1925
13 元器件 12 0 5.7186

比较运算符和逻辑运算符

1
2
3
4
df = pd.DataFrame(np.random.randint(100, size=(6, 6)),
columns=list("ABCDEF"),
index=range(1, 7))
df
A B C D E F
1 79 33 60 33 34 63
2 66 45 18 43 52 46
3 75 0 31 56 71 50
4 60 23 12 29 25 57
5 98 67 35 53 67 82
6 0 23 48 31 48 47
1
2
# 条件 A < B (A列值 < B列值) 并且B<C
df.query("A<B & B<C ")
A B C D E F
6 0 23 48 31 48 47
1
2
# 连续比较
df.query("A<B<C")
A B C D E F
6 0 23 48 31 48 47

类似于 isin / ~isin 的用法

1
2
3
4
5
lst = [i for i in range(100) if i%5==0]
df.query("A ==@lst & B== @lst")

# 等价于:
df[df["A"].isin(lst) & (df["B"].isin(lst))]
A B C D E F
3 75 0 31 56 71 50
A B C D E F
3 75 0 31 56 71 50
1
2
3
4
5
df.query("A ==@lst & F!= @lst")

# 等价于:
df[df["A"].isin(lst) & ~df["F"].isin(lst)]

A B C D E F
4 60 23 12 29 25 57
6 0 23 48 31 48 47
A B C D E F
4 60 23 12 29 25 57
6 0 23 48 31 48 47

类似于 in / not in

1
2
# A 列的值包含在 B 列 或 C 列中
df.query("A in B | A in C")
A B C D E F
4 60 23 12 29 25 57
6 0 23 48 31 48 47
1
2
# A 列的值不在 B 列中
df.query("A not in B")
A B C D E F
1 79 33 60 33 34 63
2 66 45 18 43 52 46
3 75 0 31 56 71 50
4 60 23 12 29 25 57
5 98 67 35 53 67 82
1
2
3
4
lst = [i for i in df['A'] if i%2==0]

# A 列的值不在 lst 中
df.query("A not in @lst")
A B C D E F
1 79 33 60 33 34 63
3 75 0 31 56 71 50
1
2
3
4
5
6
7
from heapq import nlargest,nsmallest

# A 列值前3 并且 B 列值前3
tj1 = nlargest(3,df.A)
tj2 = nlargest(3,df.B)

df.query("A in @tj & B in @tj2")
A B C D E F

布尔运算符 not~ 运算符否定布尔表达式

1
2
df["bools"] = df.eval("C> C.mean()")
df
A B C D E F bools
1 79 33 60 33 34 63 True
2 66 45 18 43 52 46 False
3 75 0 31 56 71 50 False
4 60 23 12 29 25 57 False
5 98 67 35 53 67 82 True
6 0 23 48 31 48 47 True
1
df.query("not bools")
A B C D E F bools
2 66 45 18 43 52 46 False
3 75 0 31 56 71 50 False
4 60 23 12 29 25 57 False
1
df.query("~bools")
A B C D E F bools
2 66 45 18 43 52 46 False
3 75 0 31 56 71 50 False
4 60 23 12 29 25 57 False
1
2
3
4
5
tj = df.eval("C> C.mean()")

# 条件成立
df.query("@tj")

A B C D E F bools
1 79 33 60 33 34 63 True
5 98 67 35 53 67 82 True
6 0 23 48 31 48 47 True
1
2
3
4
# 条件不成立
tj = df.eval("C> C.mean()")
df.query("~@tj")

A B C D E F bools
2 66 45 18 43 52 46 False
3 75 0 31 56 71 50 False
4 60 23 12 29 25 57 False
1
2
3
# 条件不成立
tj = df.eval("C> C.mean()")
df.query("not @tj")
A B C D E F bools
2 66 45 18 43 52 46 False
3 75 0 31 56 71 50 False
4 60 23 12 29 25 57 False