Pandas中的查询功能
以知乎猴子社群的数据为例进行演示:
import pandas as pd
df = pd.read_excel('cyyy2016.xlsx')
df.head(10)
购药时间 社保卡号 商品编码 商品名称 销售数量 应收金额 实收金额
0 2016-01-01 星期五 1616528 236701 三九感冒灵 7 196.0 182.00
1 2016-01-02 星期六 1616528 236701 三九感冒灵 3 84.0 84.00
2 2016-01-06 星期三 10070343428 236701 三九感冒灵 3 84.0 73.92
3 2016-01-11 星期一 13389528 236701 三九感冒灵 1 28.0 28.00
4 2016-01-15 星期五 101554328 236701 三九感冒灵 8 224.0 208.00
5 2016-01-20 星期三 13389528 236701 三九感冒灵 1 28.0 28.00
6 2016-01-31 星期日 101464928 236701 三九感冒灵 2 56.0 56.00
7 2016-02-17 星期三 11177328 236701 三九感冒灵 5 149.0 131.12
8 2016-02-22 星期一 10065687828 236701 三九感冒灵 1 29.8 26.22
9 2016-02-24 星期三 12602828 236701 三九感冒灵 4 119.2 104.89
所有操作均在Jupyter Notebook中进行
1. SELECT
从中选择“商品名称”,“销售数量”两列
SQL:
SELECT "商品名称","销售数量"
FROM cyyy
LIMIT 5
PANDAS:
df[['商品名称','销售数量']].head(5)
商品名称 销售数量
0 三九感冒灵 7
1 三九感冒灵 3
2 三九感冒灵 3
3 三九感冒灵 1
4 三九感冒灵 8
2. WHERE
从中筛选出销售数量为3件的销售记录
SQL:
SELECT *
FROM cyyy
WHERE "销售数量" = 3
LIMIT 5
PANDAS:
df[df['销售数量']==3].head(5)
购药时间 社保卡号 商品编码 商品名称 销售数量 应收金额 实收金额
1 2016-01-02 星期六 1616528 236701 三九感冒灵 3 84.0 84.00
2 2016-01-06 星期三 10070343428 236701 三九感冒灵 3 84.0 73.92
76 2016-06-05 星期日 10024054228 236703 三九感冒灵 3 89.4 78.67
78 2016-01-12 星期二 11487628 236704 感康 3 25.2 22.50
80 2016-01-27 星期三 11487628 236704 感康 3 25.2 22.50
在这个过程中,表达式df["销售数量"] == 3
会返回一个包含True/False的Series对象:
df['销售数量']==3
0 False
1 True
2 True
3 False
4 False
5 False
6 False
7 False
8 False
9 False
10 False
将表达式传入df之后会返回值为True的行
s = df['销售数量'] == 3
df[s].head(5)
购药时间 社保卡号 商品编码 商品名称 销售数量 应收金额 实收金额
1 2016-01-02 星期六 1616528 236701 三九感冒灵 3 84.0 84.00
2 2016-01-06 星期三 10070343428 236701 三九感冒灵 3 84.0 73.92
76 2016-06-05 星期日 10024054228 236703 三九感冒灵 3 89.4 78.67
78 2016-01-12 星期二 11487628 236704 感康 3 25.2 22.50
80 2016-01-27 星期三 11487628 236704 感康 3 25.2 22.50
类似于SQL中的OR、AND语句,pandas也可以设置多重筛选条件
df[(df['商品名称']=='感康')&(df['销售数量']==4)].head(5)
购药时间 社保卡号 商品编码 商品名称 销售数量 应收金额 实收金额
82 2016-02-25 星期四 103935028 236704 感康 4 33.6 29.56
89 2016-04-24 星期日 10014223328 236704 感康 4 33.6 30.00
135 2016-07-05 星期二 10030914028 861368 感康 4 38.0 33.44
4490 2016-04-25 星期一 10030914028 872293 感康 4 91.2 80.26
5175 2016-05-05 星期四 10030914028 872293 感康 4 91.2 80.26
3. GROUP BY
在Pandas中可以使用groupby()函数实现类似于SQL中的GROUP BY功能,groupby()能将数据集按某一条件分为多个组,然后对其进行某种函数运算(通常是聚合运算)。
如统计每种药品的销售记录数量
SQL:
SELECT 商品名称,count(*)
FROM cyyy
GROUP BY 商品名称
PANDAS:
df.groupby('商品名称').size().head(5)
商品名称
**盐酸阿罗洛尔片(阿尔马尔) 34
**阿替洛尔片 8
D厄贝沙坦氢氯噻嗪片(倍悦) 1
D替格瑞洛片 1
D盐酸贝尼地平片 3
dtype: int64
这里也可以使用count(),与size()不同的是,count会统计各列的非NaN项数量
df.groupby('商品名称').count().head(5)
购药时间 社保卡号 商品编码 销售数量 应收金额 实收金额
商品名称
**盐酸阿罗洛尔片(阿尔马尔) 34 34 34 34 34 34
**阿替洛尔片 8 8 8 8 8 8
D厄贝沙坦氢氯噻嗪片(倍悦) 1 1 1 1 1 1
D替格瑞洛片 1 1 1 1 1 1
D盐酸贝尼地平片 3 3 3 3 3 3
df.groupby('商品名称')['社保卡号'].count().head(5)
商品名称
**盐酸阿罗洛尔片(阿尔马尔) 34
**阿替洛尔片 8
D厄贝沙坦氢氯噻嗪片(倍悦) 1
D替格瑞洛片 1
D盐酸贝尼地平片 3
Name: 社保卡号, dtype: int64
groupby()还可以分别对各列应用不同的函数
SQL:
SELECT 商品名称,AVG(销售数量),COUNT(*)
FROM cyyy
GROUP BY 商品名称
PANDAS:
import numpy as np
df.groupby('商品名称').agg({'销售数量':np.mean,'应收金额':np.size}).head(5)
销售数量 应收金额
商品名称
**盐酸阿罗洛尔片(阿尔马尔) 2.970588 34.0
**阿替洛尔片 2.125000 8.0
D厄贝沙坦氢氯噻嗪片(倍悦) 2.000000 1.0
D替格瑞洛片 10.000000 1.0
D盐酸贝尼地平片 11.000000 3.0
同样也可以按照多个条件进行GROUPBY
SQL:
SELECT 商品名称,销售数量,COUNT(*),AVG(应收金额)
FROM cyyy
GROUP BY 商品名称,销售数量
PANDAS:
df.groupby(['商品名称','销售数量']).agg({'应收金额':[np.size,np.mean]})
应收金额
size mean
商品名称 销售数量
**盐酸阿罗洛尔片(阿尔马尔) 1 16.0 40.000000
2 9.0 80.000000
3 1.0 120.000000
4 1.0 160.000000
5 4.0 200.000000
11 1.0 440.000000
14 1.0 560.000000
15 1.0 600.000000
**阿替洛尔片 1 3.0 4.500000
2 3.0 9.000000
3 1.0 13.500000
5 1.0 22.500000
D厄贝沙坦氢氯噻嗪片(倍悦) 2 1.0 132.200000
D替格瑞洛片 10 1.0 2500.000000
D盐酸贝尼地平片 5 1.0 170.500000
8 1.0 272.800000
20 1.0 682.000000