关于Pandas版本: 本文基于 pandas2.2.0 编写。
关于本文内容更新: 随着pandas的stable版本更迭,本文持续更新,不断完善补充。
传送门: Pandas API参考目录
传送门: Pandas 版本更新及新特性
传送门: Pandas 由浅入深系列教程
本节目录
- Pandas.DataFrame.quantile()
- 语法:
- 返回值:
- 参数说明:
- q 分位
- axis 指定计算方向
- numeric_only 只计算数据类型为数值的行或列
- interpolation 插值法
- method 按列计算或整表计算
- 相关方法:
- 示例:
- 例1:计算一个或多个分位数()
- 例2、计算行或列的分位数
- 例3、默认返回分位数,设置为 `normalize=True` 则返回分位数比
- 例4:日期时间类型,日期时间差类型,也可以计算分位数
Pandas.DataFrame.quantile()
DataFrame.quantile
方法用于返回 DataFrame
行或列的分位数。
⚠️ 注意 :
- 缺失值 不会参与计算。例如[2, 4, 6, 8,pd.NA],元素数量 n = 4 n=4 n=4
DataFrame.quantile
所用计算公式,不同于【普通高中教科书 人教版2022年7月第4次印刷 数学B版 必须 第二册】第65页学到的方法。如果你需要使用教科书上的方法,则需要自己写函数。
语法:
DataFrame.quantile(q=0.5, axis=0, numeric_only=False, interpolation=‘linear’, method=‘single’)
返回值:
- Series or DataFrame
- 如果同时计算多个分位数,则返回
DataFrame
。 - 如果只计算一个分位数,则返回
Series
。
- 如果同时计算多个分位数,则返回
参数说明:
q 分位
-
q : float or array-like, default 0.5 (50% quantile) 例1
q
参数,用于指分位,取值范围0 <= q <= 1
,默认q=0.5
即计算 50% 分位数(中位数)。 该参数接受以下类型的传入:- float: 浮点数,适用于只计算一个分位数。
- array-like: 一个 类似数组,适用于同时计算多个分位数。
axis 指定计算方向
-
axis : {0 or ‘index’, 1 or ‘columns’}, default 0
axis
参数,用于控制计算方向,即计算整列数据的分位数,或计算整行数据的分位数:例2- 0 or ‘index’: 计算整列数据的分位数(默认)。
- 1 or ‘columns’ 计算整行数据的分位数。
numeric_only 只计算数据类型为数值的行或列
-
numeric_only : bool, default False
numeric_only
参数,用于控制是否只计算数据类型是数值的行或列:例3- False: 所有类型的行或列,都可以参与分位数计算(默认)。
- True: 只计算数据类型为数值的行或列。
⚠️ 注意 :
【官方定义的数值型】:
float
,int
,boolean
传送门:官方API文档实际应用中的结果是:
- 布尔型
boolean
的行或列,会报错TypeError
。 例3-3 - 即使
numeric_only=True
复数型compile
也会参与分位数计算。但是会报错TypeError
。 例3-4 - 当
numeric_only=True
时,datetime
和timedelta
类型的数据,也可以计算分位数。例5
📌 改动于 Pandas 2.0.0 : 。
numeric_only
参数的默认值,变更为False
interpolation 插值法
-
interpolation : {‘linear’, ‘lower’, ‘higher’, ‘midpoint’, ‘nearest’}
interpolation
参数,用于控制当 p o s pos pos 不是整数时的取值方法,默认interpolation=‘linear’
使用线性插值法:例4⚠️ 分位数线性插值法 :
在数组 x x x 求分位数,分为两个步骤:
- 求位置
p
o
s
pos
pos: 将数组从小到大排列,定位到数组的
p
%
p\%
p% 位置。
- p o s = 1 + ( n − 1 ) ⋅ p % pos = 1 + (n - 1) \cdot p\% pos=1+(n−1)⋅p%
- 其中, p o s pos pos 是分位数在数组中的位置, n n n 是元素总数量, p % p\% p% 是分位点。
- 求分位数
Q
p
Q_{p}
Qp: 在
p
o
s
pos
pos 位置取值。
- 如果 p o s pos pos 是整数: Q p = x p o s Q_{p} = x_{pos} Qp=xpos
- 如果
p
o
s
pos
pos 不是整数:
- 设 i i i 为小于 p o s pos pos 的最小整数, j j j 为大于 p o s pos pos 的最小整数, δ δ δ 为 p o s pos pos 的小数部分
- $Q_{p} = {x_i} + ({x_j} - {x_i}) \cdot δ $
- ‘linear’: 线性插值法, $Q_{p} = {x_i} + ({x_j} - {x_i}) \cdot δ $
- ‘lower’: 较小值 Q p = x i Q_{p} = {x_i} Qp=xi,
- ‘higher’: 较大值 Q p = x j Q_{p} = {x_j} Qp=xj,
- ‘nearest’: 最近值(较小值 x i {x_i} xi 或 较大值 x j {x_j} xj ,哪个近就取哪个) ,
- ‘midpoint’: 中间值 Q p = x i + x j 2 Q_{p} = \frac{{x_{\text{i}} + x_{\text{j}}}}{2} Qp=2xi+xj ,其实就是较小值和较大值的平均值。
- 求位置
p
o
s
pos
pos: 将数组从小到大排列,定位到数组的
p
%
p\%
p% 位置。
method 按列计算或整表计算
-
method : {‘single’, ‘table’}, default ‘single’
method
参数,是按列计算分位数(‘single’)还是整表的分位数(‘table’):- ‘single’: 所有的行或列单独计算。
- ‘table’: 计算整个表的分位数。
⚠️ 注意 :
当
method='table'
时,允许的插值方法仅有'nearest'
、'lower'
和'higher'
。
⚠️ BUG :
method=‘table’ 设计的初衷是可以计算整个DF的分位数,而不是只按行、列计算。
但是,经过测试,method='table’这个参数并没有生效。测试版本为2.2.0。
这个参数的设计初衷详见:https://github.com/pandas-dev/pandas/issues/43881
相关方法:
➡️ 相关方法
Series.quantile
分位数
示例:
测试文件下载:
本文所涉及的测试文件,如有需要,可在文章顶部的绑定资源处下载。
若发现文件无法下载,应该是资源包有内容更新,正在审核,请稍后再试。或站内私信作者索要。
例1:计算一个或多个分位数()
例1-1、创建演示数据
import pandas as pd
df = pd.DataFrame({"第1组数据": [2, 4, 6, 8, pd.NA], "第2组数据": [2, 4, 6, 8, 10]})
df
第1组数据 | 第2组数据 | |
---|---|---|
0 | 2 | 2 |
1 | 4 | 4 |
2 | 6 | 6 |
3 | 8 | 8 |
4 | <NA> | 10 |
例1-2、只计算25%分位数(第一四分位数)
df.quantile(q=0.25)
第1组数据 3.5
第2组数据 4.0
Name: 0.25, dtype: object
注意观察计算结果,第1组数据,包含缺失值,但是在计算过程中,并没有被计算到元素数量 n n n
例1-3、同时计算25%分位数(第一四分位数)和50%分位数(中位数)
df.quantile(q=[0.25, 0.5])
第1组数据 | 第2组数据 | |
---|---|---|
0.25 | 3.5 | 4.0 |
0.50 | 5.0 | 6.0 |
例2、计算行或列的分位数
例2-1、计算列的分位数,可以保持axis
参数为空,也可以使axis=0
df.quantile([0.25, 0.5]) # 等效于df.quantile([0.25,0.5],axis=0)
第1组数据 | 第2组数据 | |
---|---|---|
0.25 | 3.5 | 4.0 |
0.50 | 5.0 | 6.0 |
例2-2、计算行的分位数
df.quantile([0.25, 0.5], axis=1)
0 | 1 | 2 | 3 | 4 | |
---|---|---|---|---|---|
0.25 | 2.0 | 4.0 | 6.0 | 8.0 | 10.0 |
0.50 | 2.0 | 4.0 | 6.0 | 8.0 | 10.0 |
例2-3、如果保持默认,什么都不传递,则所有列都参与分位数计算。(为了方便观察,使用 to_frame
方法,把返回的 Series
以 DataFrame
的形式展现)
df.quantile().to_frame()
count | ||
---|---|---|
成年体数量 | 幼体的数量 | |
4 | 0 | 2 |
2 | 2 | 1 |
6 | 0 | 1 |
例3、默认返回分位数,设置为 normalize=True
则返回分位数比
例3-1、创建演示数据
import pandas as pd
df2 = pd.DataFrame(
{
"包含缺失值": [1, 2, 3, pd.NA],
"包含字符串": [1, 2, 3, "a"],
"整数型": [1, 2, 3, 4],
"浮点数": [1.0, 2.0, 3.0, 4.0],
"布尔型": [True, True, False, False],
"复数型": [1 + 1j, 2 + 1j, 3 + 1j, 4 + 1j],
}
)
df2
包含缺失值 | 包含字符串 | 整数型 | 浮点数 | 布尔型 | 复数型 | |
---|---|---|---|---|---|---|
0 | 1 | 1 | 1 | 1.0 | True | 1.0+1.0j |
1 | 2 | 2 | 2 | 2.0 | True | 2.0+1.0j |
2 | 3 | 3 | 3 | 3.0 | False | 3.0+1.0j |
3 | <NA> | a | 4 | 4.0 | False | 4.0+1.0j |
例3-2、手动筛选,不包含布尔型和复数型,观察当 numeric_only=True
会有哪些列参与计算
df2.iloc[:, 0:4].quantile([0.25, 0.5], numeric_only=True)
整数型 | 浮点数 | |
---|---|---|
0.25 | 1.75 | 1.75 |
0.50 | 2.50 | 2.50 |
df2.iloc[:, 0:5].quantile([0.25, 0.5], numeric_only=True)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[37], line ---->--> 1 df2.iloc[:,0:5].quantile([0.25, 0.5], numeric_only=Tre...
...
...6 # asanyarray is a stop-gap until gh-13105
4657 lerp_interpolation = asanyarray(add(a, diff_b_a * t, out=out))
TypeError: numpy boo
```lean subtract, the `-` operator, is not supported, use the bitwise_xor, the `^` operator, or the logical_xor function instead.
<a id="DataFrame.quantile_e3-4"></a>
例3-4、让复数型参与进来,会报错`TypeError`
```python
df2.iloc[:, [0, 1, 2, 3, 5]].quantile([0.25, 0.5], numeric_only=True)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[43], line 1
----> 1 df2.iloc[:, [0, 1, 2, 3, 5]].quantile([0.25, 0.5], numeric_only=Tr
...
...
...
File D:\ProgramData\miniconda3\envs\python3.12\Lib\site-packages\numpy\lib\function_base.py:4277, in percentile(a, q, axis, out, overwrite_input, method, keepdims, interpolation)
4275 a = np.asanyarray(a)
4276 if a.dtype.kind == "c":
-> 4277 raise TypeError("a must be an array of real numbers")
4279 q = np.true_divide(q, 100)
4280 q = asanyarray(q) # undo any decay that the ufunc performed (see gh-13105)
TypeError: a must be an array of real
```numbersue)
<a id="DataFrame.quantile_e4"></a>
### 例4:使用不同的插值法计算分位数
例4-1、默认 `interpolation=‘linear’` 使用线性插值法
```python
import pandas as pd
df3 = pd.DataFrame(
{
"包含缺失值": [1, 2, 3, pd.NA],
"整数型": [1, 2, 3, 4],
"浮点数": [1.0, 2.0, 3.0, 4.0],
}
)
df3.quantile([0.25, 0.5])
包含缺失值 | 整数型 | 浮点数 | |
---|---|---|---|
0.25 | 1.5 | 1.75 | 1.75 |
0.50 | 2.0 | 2.50 | 2.50 |
例4-2、使用平均值插值法
df3.quantile([0.25, 0.5], interpolation='midpoint')
包含缺失值 | 整数型 | 浮点数 | |
---|---|---|---|
0.25 | 1.5 | 1.5 | 1.5 |
0.50 | 2.0 | 2.5 | 2.5 |
例4:日期时间类型,日期时间差类型,也可以计算分位数
import pandas as pd
df = pd.DataFrame({'A': [1, 2],
'B': [pd.Timestamp('2010'),
pd.Timestamp('2011')],
'C': [pd.Timedelta('1 days'),
pd.Timedelta('2 days')]})
df.quantile([0.2,0.5], numeric_only=False)
A | B | C | |
---|---|---|---|
0.2 | 1.2 | 2010-03-15 00:00:00 | 1 days 04:48:00 |
0.5 | 1.5 | 2010-07-02 12:00:00 | 1 days 12:00:00 |