暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

使用SQL操作Pandas以及使用DataFrame的query函数过滤数据

漫谈大数据与数据分析 2020-04-25
2518



点击上方蓝字可以订阅哦


pandasql工具

在 Python 里 pandasql工具可以直接使用 SQL 语句来操作 Pandas,如果你是第一次使用pandasql或者版本过低,可以通过以下命令安装或升级:
pip install -U pandasql

pandasql 中的主要函数是 sqldf,它接收两个参数:一个 SQL 查询语句,还有一组环境变量 globals() 或 locals()。

类型为DataFrame的变量名会自动会注册为pandasql的表名,查询时表名用DataFrame的变量名即可。

关于pandasql支持的sql语法可参考:https://www.sqlite.org/lang.html



首先,导入库,并准备测试数据:

import pandas as pd
from pandasql import sqldf
df1 = pd.DataFrame({
'name': ['ZhangFei', 'GuanYu', 'a', 'b', 'c'],
'data1': range(5)
})
df1

Out[1]:


namedata1
0ZhangFei0
1GuanYu1
2a2
3b3
4c4

然后测试pandasql:

sqldf("select * from df1 where name ='ZhangFei'", globals())

Out[2]:


namedata1
0ZhangFei0

为了不用每次写sql都传globals(),可以定义一个函数:

pysqldf = lambda sql: sqldf(sql, globals())

再次写sql时就只需要:

pysqldf("select * from df1 order by data1 desc")

Out[3]:


namedata1
0c4
1b3
2a2
3GuanYu1
4ZhangFei0

官方测试数据:

from pandasql import sqldf, load_meat, load_births
pysqldf = lambda q: sqldf(q, globals())
meat = load_meat()
births = load_births()
pysqldf("SELECT * FROM meat LIMIT 10;").head()
Out:
date beef veal pork lamb_and_mutton broilers other_chicken turkey
0 1944-01-01 00:00:00 751 85 1280 89 None None None
1 1944-02-01 00:00:00 713 77 1169 72 None None None
2 1944-03-01 00:00:00 741 90 1128 75 None None None
3 1944-04-01 00:00:00 650 89 978 66 None None None
4 1944-05-01 00:00:00 681 106 1029 78 None None None

连接查询:

q = """SELECT
m.date, m.beef, b.births
FROM meat m
INNER JOIN births b ON m.date = b.date;"""
joined = pysqldf(q)
joined.head()

Out:


datebeefbirths
01975-01-01 00:00:00.0000002106.0265775
11975-02-01 00:00:00.0000001845.0241045
21975-03-01 00:00:00.0000001891.0268849
31975-04-01 00:00:00.0000001895.0247455
41975-05-01 00:00:00.0000001849.0254545

聚合查询:

q = """select
strftime('%Y', date) as year,
SUM(beef) as beef_total
FROM meat
GROUP BY year;"""
pysqldf(q).head()

Out:


yearbeef_total
019448801.0
119459936.0
219469010.0
3194710096.0
419488766.0



DataFrame的query方法过滤数据

在Pandas0.25版本开始,DataFrame有了query函数,若你的pandas版本较低,可通过以下命令升级:
pip install pandas  --upgrade
对于以下数据:
df = pd.DataFrame({'A': range(1, 6),
'B': range(10, 0, -2),
'C C': range(10, 5, -1)})
df
Out:

ABC C
011010
1289
2368
3447
4526
传统的过滤方法:
df[df.A > df.B]
Out:

ABC C
4526
使用query函数,可简写为
df.query('A > B')
Out:

ABC C
4526

对于存在空格的列名,可以使用反引号`:

df.query('B == `C C`')

Out:


ABC C
011010
若要使用query实现:
df[(df['A'] > df["A"].mean()) & (df['B'] < 8)]
Out:

ABC C
3447
4526
可以使用@引用变量实现:
mean = df["A"].mean()
df.query("A > @mean & B < 8")
Out:

ABC C
3447
4526

在query函数中行列索引名、字符串、and/not/or/&/|/~/not in/in/==/!=、四则运算符都是合法的。例如对于一个大数据集:

df.head()
Out:

AddressWeight
ID

1101street_163
1102street_273
1103street_282
1104street_281
1105street_464
普通过滤:
df[df['Address'].isin(["street_6", "street_7"]) & (df['Weight'] > (70 + 10)) &
(df.index.isin([1303, 2304, 2402]))]
Out:

AddressWeight
ID

1303street_782
2304street_681
2402street_782
query表达式:
df.query('(Address in ["street_6","street_7"])&(Weight>(70+10))&(ID in [1303,2304,2402])')
Out:

AddressWeight
ID

1303street_782
2304street_681
2402street_782




END -





文章转载自漫谈大数据与数据分析,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论