如何获取整数列表四分位数 解决np.quantile结果偏差问题
偏差原因
四分位数不存在唯一的通用计算标准,不同统计教材、工具采用的分位点定位规则存在差异:
- 你调用
np.quantile时未指定计算方法,NumPy默认采用线性插值规则:当分位点落在两个相邻元素之间时,会按位置权重计算两个元素的平均值作为分位值。你的测试列表共11个元素,默认规则下Q1落在14和15中间、Q3落在33和34中间,因此得到14.5、33.5的结果。 - 你预期的14、30、34结果,属于Tukey四分位数计算规则:先取整个列表的中位数作为Q2,再将列表拆分为排除Q2的下半段、上半段,分别取两段的中位数作为Q1、Q3,完全不做插值计算。
调整方案
你可以根据使用的NumPy版本选择对应修改方式,也可以手动实现规则完全可控的计算逻辑。
方案1:指定NumPy分位计算规则
如果你使用NumPy 1.22及以上版本,直接给np.quantile传入method='weibull'参数即可匹配i = q*(n+1)的分位点定位逻辑,得到预期结果:
import numpy as np intList = [5, 10, 14, 15, 26, 30, 31, 33, 34, 47, 64] def quartiles(numbers): Q1, Q2, Q3 = np.quantile( numbers, [0.25, 0.5, 0.75], axis=0, method='weibull' ) return { 'Q1': int(Q1), 'Q2': int(Q2), 'Q3': int(Q3) }
运行上述代码返回结果为{'Q1': 14, 'Q2': 30, 'Q3': 34},和预期一致。
方案2:手动实现Tukey四分位逻辑
如果你的NumPy版本较低(1.22以下无method参数),或者需要完全固定计算规则不受工具默认参数影响,可以直接手动实现逻辑,无需依赖NumPy的分位接口:
intList = [5, 10, 14, 15, 26, 30, 31, 33, 34, 47, 64] def get_median(arr): arr_len = len(arr) mid_idx = arr_len // 2 if arr_len % 2 == 1: return arr[mid_idx] return (arr[mid_idx - 1] + arr[mid_idx]) / 2 def quartiles(numbers): sorted_nums = sorted(numbers) n = len(sorted_nums) mid_idx = n // 2 Q2 = get_median(sorted_nums) # 奇数长度时拆分上下半区排除中位数本身 if n % 2 == 1: lower_part = sorted_nums[:mid_idx] upper_part = sorted_nums[mid_idx+1:] else: lower_part = sorted_nums[:mid_idx] upper_part = sorted_nums[mid_idx:] Q1 = get_median(lower_part) Q3 = get_median(upper_part) return { 'Q1': Q1, 'Q2': Q2, 'Q3': Q3 }
该实现不依赖第三方库,对任意长度的有序/无序列表都能返回Tukey规则下的四分位值,你的测试列表运行结果同样为{'Q1': 14, 'Q2': 30, 'Q3': 34}。
内容的提问来源于stack exchange,提问作者crawfish
相关产品推荐
相关产品推荐

