06_Pandas索引运算
文章目录
- 1 DataFrame结构
- 1.1 column/index/value
- 1.2 单独取列/行
- 2 基于位置定位
- 2.1 行选取
- 2.2 列选取
- 2.3 行列交叉选取
- 3 基于标签定位
- 3.1 行选取
- 3.2 列选取
- 3.3 行列交叉选取
- 3.3.1 query函数
- 3.3.2 isin函数
- 3.4 多条件索引
Pandas索引操作有两种常见类型:
- 基于位置的索引(Position-based Indexing)
- 基于标签的索引(Label-based Indexing)
实际操作中,第二种操作更常用。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
1 DataFrame结构
1.1 column/index/value
DataFrame主要包含以下三个部分:
column
:列标签(Index对象)index
:行标签(Index对象)value
:数据域
基于标签定位就是靠Index
对象,在此之外还有动态映射出来的虚拟列号和行号,可以直接基于数组下标进行定位,也就是基于位置定位。
df = pd.read_excel('data/source_data.xlsx')
df.index = np.arange(1001, 1008)
df
流量级别 | 投放地区 | 访客数 | 支付转化率 | 客单价 | 支付金额 | |
---|---|---|---|---|---|---|
1001 | 一级 | A区 | 44300 | 11.78% | 58.79 | 306887.83 |
1002 | 一级 | B区 | 30612 | 13.85% | 86.64 | 367338.10 |
1003 | 一级 | C区 | 18389 | 2.50% | 0.28 | 129.58 |
1004 | 一级 | B区 | 4509 | 10.73% | 64.12 | 31035.14 |
1005 | 一级 | C区 | 3769 | 5.73% | 92.91 | 20068.20 |
1006 | 一级 | A区 | 2424 | 22.07% | 89.33 | 47791.60 |
1007 | 一级 | C区 | 2412 | 8.21% | 56.04 | 11096.42 |
1.2 单独取列/行
DataFrame
的行和列单独取出来都是一个Series
对象,事实上,DataFrame
对象就是将多个 Series
对象组合到一起的结果。
# 单独取一列,两种方式
print(df['客单价'], end='\n\n')
print(df.客单价)
1001 58.79
1002 86.64
1003 0.28
1004 64.12
1005 92.91
1006 89.33
1007 56.04
Name: 客单价, dtype: float641001 58.79
1002 86.64
1003 0.28
1004 64.12
1005 92.91
1006 89.33
1007 56.04
Name: 客单价, dtype: float64
# 单独取一行,两种方式
print(df.loc[1005], end='\n\n')
print(df.iloc[4])
流量级别 一级
投放地区 C区
访客数 3769
支付转化率 5.73%
客单价 92.91
支付金额 20068.2
Name: 1005, dtype: object流量级别 一级
投放地区 C区
访客数 3769
支付转化率 5.73%
客单价 92.91
支付金额 20068.2
Name: 1005, dtype: object
2 基于位置定位
基于位置索引使用iloc[行号, 列号]
进行选取。
df
流量级别 | 投放地区 | 访客数 | 支付转化率 | 客单价 | 支付金额 | |
---|---|---|---|---|---|---|
1001 | 一级 | A区 | 44300 | 11.78% | 58.79 | 306887.83 |
1002 | 一级 | B区 | 30612 | 13.85% | 86.64 | 367338.10 |
1003 | 一级 | C区 | 18389 | 2.50% | 0.28 | 129.58 |
1004 | 一级 | B区 | 4509 | 10.73% | 64.12 | 31035.14 |
1005 | 一级 | C区 | 3769 | 5.73% | 92.91 | 20068.20 |
1006 | 一级 | A区 | 2424 | 22.07% | 89.33 | 47791.60 |
1007 | 一级 | C区 | 2412 | 8.21% | 56.04 | 11096.42 |
DataFrame索引方式大体分为下面四种,其中行和列类似Numpy的索引运算,可以使用切片索引、花式索引、布尔索引。
df[列][行]
:先选列再选行,链式索引,不推荐df.loc[行][列]/df.iloc[行][列]
:先取行再取列,链式索引可能产生副本,修改不会反映到原对象,不推荐df.loc[行, 列]
:标签方式一次性定位,推荐!df.iloc[行, 列]
:位置方式一次性定位,推荐!
2.1 行选取
# 连续选取,使用切片索引
df.iloc[2:5]
流量级别 | 投放地区 | 访客数 | 支付转化率 | 客单价 | 支付金额 | |
---|---|---|---|---|---|---|
1003 | 一级 | C区 | 18389 | 2.50% | 0.28 | 129.58 |
1004 | 一级 | B区 | 4509 | 10.73% | 64.12 | 31035.14 |
1005 | 一级 | C区 | 3769 | 5.73% | 92.91 | 20068.20 |
花式索引需要构造列表,将列表作为单个参数传入。
# 跨行选取,使用花式索引
df.iloc[[1, 3, 6]]
流量级别 | 投放地区 | 访客数 | 支付转化率 | 客单价 | 支付金额 | |
---|---|---|---|---|---|---|
1002 | 一级 | B区 | 30612 | 13.85% | 86.64 | 367338.10 |
1004 | 一级 | B区 | 4509 | 10.73% | 64.12 | 31035.14 |
1007 | 一级 | C区 | 2412 | 8.21% | 56.04 | 11096.42 |
2.2 列选取
df.iloc[:, 1:4]
投放地区 | 访客数 | 支付转化率 | |
---|---|---|---|
1001 | A区 | 44300 | 11.78% |
1002 | B区 | 30612 | 13.85% |
1003 | C区 | 18389 | 2.50% |
1004 | B区 | 4509 | 10.73% |
1005 | C区 | 3769 | 5.73% |
1006 | A区 | 2424 | 22.07% |
1007 | C区 | 2412 | 8.21% |
2.3 行列交叉选取
df.iloc[2:5, [1, 5]]
投放地区 | 支付金额 | |
---|---|---|
1003 | C区 | 129.58 |
1004 | B区 | 31035.14 |
1005 | C区 | 20068.20 |
3 基于标签定位
基于标签定位使用loc['行标签', '列标签']
进行选取。
注意:loc
的切片是包含结束值的!!!
df
流量级别 | 投放地区 | 访客数 | 支付转化率 | 客单价 | 支付金额 | |
---|---|---|---|---|---|---|
1001 | 一级 | A区 | 44300 | 11.78% | 58.79 | 306887.83 |
1002 | 一级 | B区 | 30612 | 13.85% | 86.64 | 367338.10 |
1003 | 一级 | C区 | 18389 | 2.50% | 0.28 | 129.58 |
1004 | 一级 | B区 | 4509 | 10.73% | 64.12 | 31035.14 |
1005 | 一级 | C区 | 3769 | 5.73% | 92.91 | 20068.20 |
1006 | 一级 | A区 | 2424 | 22.07% | 89.33 | 47791.60 |
1007 | 一级 | C区 | 2412 | 8.21% | 56.04 | 11096.42 |
3.1 行选取
df.loc[1003: 1005]
流量级别 | 投放地区 | 访客数 | 支付转化率 | 客单价 | 支付金额 | |
---|---|---|---|---|---|---|
1003 | 一级 | C区 | 18389 | 2.50% | 0.28 | 129.58 |
1004 | 一级 | B区 | 4509 | 10.73% | 64.12 | 31035.14 |
1005 | 一级 | C区 | 3769 | 5.73% | 92.91 | 20068.20 |
结合布尔索引将判断结果作为掩码可以进行筛选数据。
df.loc[df['客单价'] > 80]
流量级别 | 投放地区 | 访客数 | 支付转化率 | 客单价 | 支付金额 | |
---|---|---|---|---|---|---|
1002 | 一级 | B区 | 30612 | 13.85% | 86.64 | 367338.1 |
1005 | 一级 | C区 | 3769 | 5.73% | 92.91 | 20068.2 |
1006 | 一级 | A区 | 2424 | 22.07% | 89.33 | 47791.6 |
3.2 列选取
df[['投放地区', '客单价']]
投放地区 | 客单价 | |
---|---|---|
1001 | A区 | 58.79 |
1002 | B区 | 86.64 |
1003 | C区 | 0.28 |
1004 | B区 | 64.12 |
1005 | C区 | 92.91 |
1006 | A区 | 89.33 |
1007 | C区 | 56.04 |
df.loc[:, ['投放地区', '客单价']]
投放地区 | 客单价 | |
---|---|---|
1001 | A区 | 58.79 |
1002 | B区 | 86.64 |
1003 | C区 | 0.28 |
1004 | B区 | 64.12 |
1005 | C区 | 92.91 |
1006 | A区 | 89.33 |
1007 | C区 | 56.04 |
3.3 行列交叉选取
df.loc[(df['投放地区'] == 'B区') | (df['投放地区'] == 'C区'), ['投放地区', '访客数', '客单价']]
投放地区 | 访客数 | 客单价 | |
---|---|---|---|
1002 | B区 | 30612 | 86.64 |
1003 | C区 | 18389 | 0.28 |
1004 | B区 | 4509 | 64.12 |
1005 | C区 | 3769 | 92.91 |
1007 | C区 | 2412 | 56.04 |
3.3.1 query函数
query(exp, inplace=False
)`:可以使用Python布尔表达式进行选取符合条件的行。
df.query("访客数 > 3000 and 访客数 < 20000")[['投放地区', '访客数', '客单价']]
投放地区 | 访客数 | 客单价 | |
---|---|---|---|
1003 | C区 | 18389 | 0.28 |
1004 | B区 | 4509 | 64.12 |
1005 | C区 | 3769 | 92.91 |
3.3.2 isin函数
isin()
函数:判断是否等于列表中的值。
df.loc[df['投放地区'].isin(['B区', 'C区']), ['投放地区', '访客数', '客单价']]
投放地区 | 访客数 | 客单价 | |
---|---|---|---|
1002 | B区 | 30612 | 86.64 |
1003 | C区 | 18389 | 0.28 |
1004 | B区 | 4509 | 64.12 |
1005 | C区 | 3769 | 92.91 |
1007 | C区 | 2412 | 56.04 |
3.4 多条件索引
在使用索引筛选出数据之后,只需要加个统计函数的尾巴就可以直接算出统计数值。
mean()
#计算均值std()
#计算标准差median()
#计算中位数max()
#计算最大值min()
#计算最小值
print('客单价平均值', df['客单价'].mean())
客单价平均值 64.01571428571428
搭配布尔索引进一步进行统计筛选,使用&
、|
时,表达式注意必须要用括号()
括起来。
df.loc[(df['访客数'] > df['访客数'].mean()) & (df['客单价'] > df['客单价'].mean())]
流量级别 | 投放地区 | 访客数 | 支付转化率 | 客单价 | 支付金额 | |
---|---|---|---|---|---|---|
1002 | 一级 | B区 | 30612 | 13.85% | 86.64 | 367338.1 |