文章目录
-
- [1.4 查询,排序,分组汇总数据](#1.4 查询,排序,分组汇总数据)
-
- [1.4.1 查询数据](#1.4.1 查询数据)
- [1.4.2 排序数据](#1.4.2 排序数据)
- [1.4.2 分组汇总](#1.4.2 分组汇总)
- [1.5 与数组或列表的转换](#1.5 与数组或列表的转换)
- [1.6 自定义函数](#1.6 自定义函数)
1.4 查询,排序,分组汇总数据
1.4.1 查询数据
对 DataFrame 数据按照一定条件查询时,一般会用到一些比较运算符,例如:>, >=, ==, <, <=, !=。条件查询一般只针对列数据,查询时,Pandas 首先生成布尔索引 True 或 False,再通过指定索引生成查询后的数据。
例如,下面的代码:
python
import pandas as pd
df = pd.DataFrame({'姓名':['张三', '李四', '王五'], '统计学': [85, 68, 90],
'高数': [82, 63, 88], '英语': [84, 90, 78]})
df
| | 姓名 | 统计学 | 高数 | 英语 |
| 0 | 张三 | 85 | 82 | 84 |
| 1 | 李四 | 68 | 63 | 90 |
2 | 王五 | 90 | 88 | 78 |
---|
python
df['统计学'] > 83 # 统计学成绩大于83的布尔索引
0 True
1 False
2 True
Name: 统计学, dtype: bool
python
df[df['统计学'] > 83] # 生成统计学成绩大于83的数据
| | 姓名 | 统计学 | 高数 | 英语 |
| 0 | 张三 | 85 | 82 | 84 |
2 | 王五 | 90 | 88 | 78 |
---|
对于多条件查询,可以用&
表示并:两个条件都要满足,用|
表示或:两个条件满足一个即可。举例:
python
df[(df['高数'] > 65) & (df['英语'] > 80)] # 查询高数成绩大于65,英语成绩大于80的数据,注意小括号
| | 姓名 | 统计学 | 高数 | 英语 |
0 | 张三 | 85 | 82 | 84 |
---|
python
df[(df['高数']> 65) | (df['英语'] > 80)] # 查询高数成绩大于65,英语成绩大于80的数据,注意小括号
| | 姓名 | 统计学 | 高数 | 英语 |
| 0 | 张三 | 85 | 82 | 84 |
| 1 | 李四 | 68 | 63 | 90 |
2 | 王五 | 90 | 88 | 78 |
---|
1.4.2 排序数据
在处理数据时,经常要对数据排序。 Pandas 提供了一个方便的函数sort_values
对数值进行排序,它的使用语法如下:
DataFrame.sort_values(by, axis=0, ascending=True, inplace=False, na_position='last', ignore_index=False)} | |
---|---|
by | 需要排序的列名(axis=0)或行名(axis=1),可以有多个 |
axis | 0 表示对列排序,1 表示对行排序,默认是0 |
ascending | 升序还是降序,默认是升序排列 |
inplace | 是否替换原有数据,默认为 False 不替换 |
na_position | 缺失值 NaN 放在排序的前面还是后面,默认是放在后面 |
ignore_index | 如果为 True,则排序后的行号重新标号,默认是 False |
对统计学成绩升序排列:
python
df.sort_values(by = '统计学')
| | 姓名 | 统计学 | 高数 | 英语 |
| 1 | 李四 | 68 | 63 | 90 |
| 0 | 张三 | 85 | 82 | 84 |
2 | 王五 | 90 | 88 | 78 |
---|
对统计学与高数成绩降序排序:
python
df.sort_values(by = ['统计学', '高数'], ascending = False)
| | 姓名 | 统计学 | 高数 | 英语 |
| 2 | 王五 | 90 | 88 | 78 |
| 0 | 张三 | 85 | 82 | 84 |
1 | 李四 | 68 | 63 | 90 |
---|
在参数by
中,统计学在前,高数在后,表示:先把统计学成绩降序排序,若统计学成绩有相同的,再按高数成绩降序排序。
由于排序时列标签经常被打乱,可以使用ignore_index = True
重新排列标签,inplace = True
改变原始数据。
python
df.sort_values(by = '统计学') # 排序,可以看出列标也发生了变动
| | 姓名 | 统计学 | 高数 | 英语 |
| 1 | 李四 | 68 | 63 | 90 |
| 0 | 张三 | 85 | 82 | 84 |
2 | 王五 | 90 | 88 | 78 |
---|
python
df.sort_values(by = '统计学', ignore_index = True) # 排序后重新排列标签
| | 姓名 | 统计学 | 高数 | 英语 |
| 0 | 李四 | 68 | 63 | 90 |
| 1 | 张三 | 85 | 82 | 84 |
2 | 王五 | 90 | 88 | 78 |
---|
python
df.sort_values(by = '统计学', ignore_index = True) # 排序后,没有替换原始数据
df
| | 姓名 | 统计学 | 高数 | 英语 |
| 0 | 张三 | 85 | 82 | 84 |
| 1 | 李四 | 68 | 63 | 90 |
2 | 王五 | 90 | 88 | 78 |
---|
python
df.sort_values(by = '统计学', ignore_index = True, inplace = True) # 排序后,替换了原始数据
df
| | 姓名 | 统计学 | 高数 | 英语 |
| 0 | 李四 | 68 | 63 | 90 |
| 1 | 张三 | 85 | 82 | 84 |
2 | 王五 | 90 | 88 | 78 |
---|
1.4.2 分组汇总
在数据分析时,经常也需要将数据分组汇总。例如,在统计学生的期末考试成绩时,可能需要根据专业或者班级来分别计算平均成绩、最高成绩等。此时,可以利用 Pandas 的groupby
函数方便地实现这些功能。
groupby 经常结合一些汇总统计量使用,例如 mean(均值),max(最大值),min(最小值),median(中位数),std(标准差),mad(平均绝对偏差),count(计数),skew(均值),quantile(分位数)。
下面的代码按性别汇总了平均成绩:
python
df = pd.DataFrame([['张三', '一班', '男', 85, 68, 90], ['李四','二班', '男', 82, 63, 88], ['王五', '二班', '女',84, 90,78], ['魏小小','三班', '女',75, 68, 80],\
['马小倩', '二班', '女',69, 55, 63], ['陈小虎', '一班', '男', 89, 95, 93]], columns=['姓名','班级','性别','统计学','高数','英语'])
df
| | 姓名 | 班级 | 性别 | 统计学 | 高数 | 英语 |
| 0 | 张三 | 一班 | 男 | 85 | 68 | 90 |
| 1 | 李四 | 二班 | 男 | 82 | 63 | 88 |
| 2 | 王五 | 二班 | 女 | 84 | 90 | 78 |
| 3 | 魏小小 | 三班 | 女 | 75 | 68 | 80 |
| 4 | 马小倩 | 二班 | 女 | 69 | 55 | 63 |
5 | 陈小虎 | 一班 | 男 | 89 | 95 | 93 |
---|
python
df.groupby('性别').mean(numeric_only = True) # 按性别汇总平均成绩, numeric_only = True 表示仅选择对函数有效的数据列
| | 统计学 | 高数 | 英语 |
| 性别 | | | |
| 女 | 76.000000 | 71.000000 | 73.666667 |
男 | 85.333333 | 75.333333 | 90.333333 |
---|
python
df.groupby(['班级', '性别']).mean() # 按班级、性别汇总平均成绩
| | | 统计学 | 高数 | 英语 |
| 班级 | 性别 | | | |
| 一班 | 男 | 87.0 | 81.5 | 91.5 |
| 三班 | 女 | 75.0 | 68.0 | 80.0 |
| 二班 | 女 | 76.5 | 72.5 | 70.5 |
二班 | 男 | 82.0 | 63.0 | 88.0 |
---|
若要汇总多个统计量,则可以跟agg
方法,例如,下面的代码按照班级,汇总了每个班的最高、最低、平均成绩。
python
df.groupby(['班级', '性别']).agg(['max', 'min', 'mean']) # 汇总了每个班每个性别的最高、最低、平均成绩
| | | 统计学 ||| 高数 ||| 英语 |||
| | | max | min | mean | max | min | mean | max | min | mean |
| 班级 | 性别 | | | | | | | | | |
| 一班 | 男 | 89 | 85 | 87.0 | 95 | 68 | 81.5 | 93 | 90 | 91.5 |
| 三班 | 女 | 75 | 75 | 75.0 | 68 | 68 | 68.0 | 80 | 80 | 80.0 |
| 二班 | 女 | 84 | 69 | 76.5 | 90 | 55 | 72.5 | 78 | 63 | 70.5 |
二班 | 男 | 82 | 82 | 82.0 | 63 | 63 | 63.0 | 88 | 88 | 88.0 |
---|
1.5 与数组或列表的转换
使用 Pandas 中的values
方法可以将 DataFrame 数据转化为 Numpy 的数组形式。例如,对于前面的数据例子:
python
df = pd.DataFrame({'姓名':['张三', '李四', '王五'], '统计学': [85, 68, 90],
'高数': [82, 63, 88], '英语': [84, 90, 78]})
df[['统计学', '高数', '英语']].values
array([[85, 82, 84],
[68, 63, 90],
[90, 88, 78]])
也可以对某列数据,使用tolist()
方法,将该列数据转化为 Python 本身的列表类型 list:
python
df['统计学'].tolist()
[85, 68, 90]
除了字典类型外,Pandas 也支持将一维或二维的数组或列表转化成 DataFrame 类型。
python
a = [1, 2, 3]
pd.DataFrame(a)
| | 0 |
| 0 | 1 |
| 1 | 2 |
2 | 3 |
---|
python
a = [[1, 2, 3], [4, 5, 6]]
pd.DataFrame(a)
| | 0 | 1 | 2 |
| 0 | 1 | 2 | 3 |
1 | 4 | 5 | 6 |
---|
python
import numpy as np
b = np.array([3, 3, 4])
pd.DataFrame(b)
| | 0 |
| 0 | 3 |
| 1 | 3 |
2 | 4 |
---|
python
c = np.matrix([[1, 2], [3, 4]])
pd.DataFrame(c)
| | 0 | 1 |
| 0 | 1 | 2 |
1 | 3 | 4 |
---|
1.6 自定义函数
Pandas 可以使用到apply
调用自定义函数。
python
import numpy as np
df['统计学'].apply(np.sqrt) # 调用 Numpy 中的求平方根函数对统计学成绩每个元素求平方根
0 9.219544
1 8.246211
2 9.486833
Name: 统计学, dtype: float64
我们可以使用lambda
定义一个匿名函数在apply
里面调用:
python
df['高数'].apply(lambda x : x - 10) # 对每一个高数成绩都减去 10 分
0 72
1 53
2 78
Name: 高数, dtype: int64
apply
也可以调用更复杂的自定义函数,例如,下面定义一个成绩替换函数,将分数替换为"优良中差":
python
def replace_score(x):
if x >= 90:
return '优'
elif x >= 80:
return '良'
elif x >= 60:
return '中'
else:
return '差'
df['英语'].apply(replace_score)
0 良
1 优
2 中
Name: 英语, dtype: object