Python SciPy Stats
最后修改于 2025年3月8日
本教程将使用 SciPy 库中的 scipy.stats
模块,探索 Python 中的统计分析,该模块非常适合高级数据科学任务。
scipy.stats
模块提供了用于描述性统计、概率分布和假设检验的工具,其功能远远超出了 Python 本身 statistics
模块的基本能力。
安装 SciPy
$ pip install scipy
使用 pip
安装 SciPy,以便访问 stats
模块及其强大的统计函数。
SciPy Stats 均值和中位数
均值是数据集的平均值,而中位数是排序后数据集的中间值,它对异常值不敏感。
#!/usr/bin/python from scipy import stats import numpy as np sales = [1200, 1500, 1300, 1700, 5000] # Monthly sales in USD mean = np.mean(sales) median = np.median(sales) print(f"Mean Sales: ${mean:.2f}") print(f"Median Sales: ${median:.2f}")
我们导入 scipy.stats
和 numpy
以进行高效的数组操作。sales
列表代表月度收入。我们使用 np.mean
和 np.median
进行计算。
均值 (2,340 美元) 受异常值 (5,000 美元) 的影响而偏斜,而中位数 (1,500 美元) 更能反映典型销售情况,这表明 scipy.stats
与 NumPy 的集成。
$ ./mean_median.py Mean Sales: $2340.00 Median Sales: $1500.00
SciPy Stats 众数
众数标识数据集中最频繁出现的值,适用于分类或离散数据分析。
#!/usr/bin/python from scipy import stats ratings = [5, 4, 5, 3, 4, 5, 2, 4, 5] # Customer satisfaction scores mode_result = stats.mode(ratings) print(f"Mode: {mode_result.mode[0]}, Count: {mode_result.count[0]}")
ratings
列表模拟客户反馈(1-5 分制)。stats.mode
返回一个 ModeResult
对象,其中包含 mode
(最频繁出现的值)和 count
(其频率)。在这里,5 出现了 4 次。
$ ./mode.py Mode: 5, Count: 4
SciPy Stats 方差和标准差
方差衡量数据围绕均值的平方差的平均值。标准差是方差的平方根,表示在原始单位下的典型偏差。
#!/usr/bin/python from scipy import stats import numpy as np temps = [22.5, 23.0, 21.8, 24.1, 22.9] # Daily temperatures (°C) variance = np.var(temps, ddof=1) # Sample variance stdev = np.std(temps, ddof=1) # Sample standard deviation print(f"Variance: {variance:.2f} °C²") print(f"Standard Deviation: {stdev:.2f} °C")
我们使用温度数据计算样本方差和标准差 (ddof=1
表示样本,而非总体)。方差 (0.85 °C²) 显示了以平方单位表示的离散度,而标准差 (0.92 °C) 更易于解释。
$ ./var_stdev.py Variance: 0.85 °C² Standard Deviation: 0.92 °C
SciPy Stats 正态分布
正态分布用钟形曲线模拟连续数据,由均值和标准差定义,在自然现象中很常见。
#!/usr/bin/python from scipy import stats # IQ scores: mean=100, std=15 iq_dist = stats.norm(loc=100, scale=15) prob_above_120 = 1 - iq_dist.cdf(120) sample = iq_dist.rvs(size=5) print(f"P(IQ > 120): {prob_above_120:.3f}") print(f"Random IQs: {sample}")
我们用正态分布 (loc
= 均值, scale
= 标准差) 来模拟智商分数。cdf(120)
给出 120 以下的累积概率,因此 1 - cdf
是超过 120 的概率。rvs
生成随机样本。
这对于心理学或教育学中的模拟或概率评估很有用。
$ ./normal_dist.py P(IQ > 120): 0.091 Random IQs: [ 95.2 112.7 88.4 104.1 99.6] # Values may vary
SciPy Stats T 检验
T 检验比较均值,以评估差异是否具有统计学意义,广泛用于假设检验。
#!/usr/bin/python from scipy import stats group1 = [85, 88, 90, 87, 86] # Test scores, method A group2 = [90, 92, 89, 94, 91] # Test scores, method B t_stat, p_val = stats.ttest_ind(group1, group2) print(f"T-Statistic: {t_stat:.2f}") print(f"P-Value: {p_val:.3f}")
我们比较两种教学方法的测试成绩。ttest_ind
执行独立样本 t 检验,返回 t 统计量和 p 值。较低的 p 值 ( < 0.05) 表明存在显著差异。
这里,p=0.013 表明方法 B 可能会提高成绩,这是教育研究中的常见分析。
$ ./ttest.py T-Statistic: -2.98 P-Value: 0.013
SciPy Stats 相关性
相关系数衡量两个变量之间的线性关系,范围从 -1(完全负相关)到 1(完全正相关)。
#!/usr/bin/python from scipy import stats hours = [2, 3, 4, 5, 6] # Study hours scores = [65, 70, 75, 85, 90] # Exam scores r, p = stats.pearsonr(hours, scores) print(f"Pearson Correlation: {r:.2f}") print(f"P-Value: {p:.3f}")
我们测试学习时间和考试成绩之间是否存在相关性。pearsonr
计算皮尔逊相关系数和 p 值。较高的 r
(0.97) 和较低的 p 值 (0.006) 证实了强正相关关系。
$ ./correlation.py Pearson Correlation: 0.97 P-Value: 0.006
SciPy Stats 峰度
峰度衡量分布的“尾部”特征,指示数据与正态分布相比是具有重尾还是轻尾。正峰度意味着重尾(更多异常值),而负峰度意味着轻尾。
#!/usr/bin/python from scipy import stats import numpy as np # Daily stock returns (%) for a tech company returns = [0.5, -0.3, 1.2, -2.5, 0.8, 3.1, -1.8, 0.2, 4.0, -3.2] kurt = stats.kurtosis(returns) print(f"Kurtosis of Returns: {kurt:.2f}")
我们分析每日股票收益,这是一个常见的金融数据集。returns
列表模拟了 10 天内股票价格的百分比变化。stats.kurtosis
计算了超额峰度(相对于正态分布,其中峰度 = 0)。
0.73 的峰度表明比正态分布具有更重的尾部,这表明价格波动更极端——这对于金融风险评估很有用。
$ ./kurtosis.py Kurtosis of Returns: 0.73
SciPy Stats 偏度
偏度衡量分布的非对称性。正偏度意味着右尾较长(例如,收入数据),而负偏度表示左尾较长(例如,失效时间)。
#!/usr/bin/python from scipy import stats import numpy as np # Annual incomes (thousands USD) in a small town incomes = [25, 30, 35, 40, 45, 50, 60, 80, 120, 200] skewness = stats.skew(incomes) print(f"Skewness of Incomes: {skewness:.2f}")
incomes
列表代表年收入,这是收入数据中由于少数高收入者而出现的典型情况。stats.skew
计算偏度。正值 (1.46) 证实了右偏分布,这在收入研究中很常见。
这有助于经济学家理解财富分配并识别人口中的不平等趋势。
$ ./skew.py Skewness of Incomes: 1.46
SciPy Stats 查找重复项
find_repeats 函数可识别数组中的重复值及其计数,有助于发现离散数据中的模式或异常。
#!/usr/bin/python from scipy import stats import numpy as np # Customer purchase counts in a week purchases = [1, 2, 3, 2, 4, 1, 2, 5, 1, 3] repeats = stats.find_repeats(purchases) print(f"Repeated Values: {repeats.values}") print(f"Counts: {repeats.counts}")
purchases
数组跟踪每个客户购买的商品数量。stats.find_repeats
返回一个 FindRepeatsResult
对象,其中包含 values
(重复的数字)和 counts
(它们重复的次数)。
这里,1 和 2 出现了多次(3 次和 3 次),这表明小额购买的频率很高。这对于零售分析以优化库存或促销活动很有价值。
$ ./find_repeats.py Repeated Values: [1. 2. 3.] Counts: [3 3 2]
SciPy Stats 描述
describe 函数提供数据集的摘要,包括计数、均值、方差、偏度、峰度以及最小值/最大值,从而提供快速概览。
#!/usr/bin/python from scipy import stats import numpy as np # Patient wait times (minutes) in a clinic wait_times = [10, 15, 12, 20, 25, 18, 30, 22, 35, 40] summary = stats.describe(wait_times) print(f"Number of Observations: {summary.nobs}") print(f"Mean: {summary.mean:.2f} minutes") print(f"Variance: {summary.variance:.2f} min²") print(f"Skewness: {summary.skewness:.2f}") print(f"Kurtosis: {summary.kurtosis:.2f}") print(f"Min: {summary.minmax[0]}, Max: {summary.minmax[1]}")
wait_times
列表模拟了医疗保健环境中的患者等待时间。stats.describe
返回一个 DescribeResult
对象,其中包含关键统计数据,可以通过 nobs
(计数)和 mean
等属性进行访问。
摘要显示平均等待时间为 22.7 分钟,轻微正偏度 (0.47) 和负峰度 (-0.73),表明分布更平坦。这有助于诊所评估服务效率和患者体验。
$ ./describe.py Number of Observations: 10 Mean: 22.70 minutes Variance: 90.46 min² Skewness: 0.47 Kurtosis: -0.73 Min: 10, Max: 40
SciPy Stats 线性回归
线性回归模拟因变量与一个或多个自变量之间的关系,并预测趋势。
#!/usr/bin/python from scipy import stats ad_spend = [100, 200, 300, 400, 500] # Ad budget ($) sales = [1200, 1500, 1800, 2100, 2400] # Sales ($) slope, intercept, r, p, se = stats.linregress(ad_spend, sales) print(f"Slope: {slope:.2f}, Intercept: {intercept:.2f}") print(f"R²: {r**2:.3f}, P-Value: {p:.3f}")
我们根据广告支出对销售额进行建模。linregress
返回斜率、截距、相关系数 (r
)、p 值和标准误差。斜率 (2.4) 表明每花费 1 美元的广告费可以带来 2.40 美元的销售额。
R² (1.0) 表明完美拟合,但实际数据会显示更多变异。这对于营销分析很有用。
$ ./regression.py Slope: 2.40, Intercept: 960.00 R²: 1.000, P-Value: 0.000
最佳实践
- 使用 NumPy 数组:为了提高效率,请将列表转换为数组。
- 检查假设:对于 t 检验,请验证正态性。
- 解释 P 值:小的 p 值(< 0.05)表明存在统计学意义。
- 记录模型:记下使用的分布参数。
来源
本教程展示了 scipy.stats
在高级统计分析中的应用,从分布到回归,并附有实际示例。
作者
列出所有 Python 教程。