当前位置: 首页 > news >正文

描述性统计——让数据说话

第03篇:描述性统计——让数据说话

写在前面:大家好,我是蓝皮怪!前两篇我们聊了统计学的基本概念和数据类型,这一篇我们要正式进入数据分析的第一步——描述性统计。别被名字吓到,其实就是用一组数字,把一堆杂乱的数据变得有条理、能看懂。你会发现,很多生活中的"平均分"、“中位数”、“标准差”,其实都是描述性统计量。今天我们就来聊聊,怎么用这些数字,把数据的故事讲清楚。

🎯 这篇文章你能学到什么

  • 描述性统计的核心概念和作用
  • 常见的统计量有哪些,怎么用、怎么选
  • 生活化案例和常见误区
  • 简单的代码演示和基础可视化
  • 如何用这些统计量总结和解读数据

1. 从生活说起:为什么要学描述性统计?

你有没有遇到过这些场景:

📊 看成绩单时:老师说"这次数学平均分75分",但你发现大部分同学都没考到75分?

💰 聊工资时:新闻说"本市平均工资6000元",可你和身边朋友都没达到?

🏠 看房价时:中介说"本小区房价中位数5000/平",这和平均价有啥区别?

这些问题,其实都和描述性统计量有关。它们帮我们用数字快速看懂一堆数据的"全貌",也能避免被"平均数陷阱"忽悠。


2. 位置类统计量:数据的"中心"在哪里?

2.1 算术平均数(非分组数据)

  • 定义:所有数据之和除以数据个数。
  • 公式
    x ˉ = 1 n ∑ i = 1 n x i \bar{x} = \frac{1}{n} \sum_{i=1}^n x_i xˉ=n1i=1nxi
  • 举例:5个人的身高分别为160、165、170、175、180cm,平均身高=(160+165+170+175+180)/5=170cm。
  • 适用场景:原始数据已知,数据分布较对称、无极端值。
  • 优缺点:简单直观,但对极端值敏感。
  • 注意:平均数不等于"典型水平",极端值会拉高或拉低均值。
【例子与代码】

(1)生活化例子:

假设你和4个朋友的月工资分别是5000、6000、7000、8000、20000元。你们想知道大家的平均工资是多少。

  • 总工资:
    5000 + 6000 + 7000 + 8000 + 20000 = 46000 5000 + 6000 + 7000 + 8000 + 20000 = 46000 5000+6000+7000+8000+20000=46000
  • 人数 = 5
  • 平均工资 = 46000 / 5 = 9200元

你会发现,虽然平均工资是9200元,但其实只有一个人远高于这个数,其他人都没达到,这就是极端值影响均值的典型例子。

(2)Python代码实现:

import numpy as np
salaries = np.array([5000, 6000, 7000, 8000, 20000])
print('平均工资:', np.mean(salaries))

输出:

平均工资: 9200.0

2.2 算术平均数(分组数据)

  • 定义:数据已分组时,用组中值近似每组数据。
  • 公式
    x ˉ = ∑ i = 1 k f i m i N \bar{x} = \frac{\sum_{i=1}^k f_i m_i}{N} xˉ=Ni=1kfimi
    其中 f i f_i fi 为第 i i i 组频数, m i m_i mi 为组中值, N N N 为总频数。
  • 举例:三组组中值10、20、30,频数2、3、5,则均值为
    均值 = 2 × 10 + 3 × 20 + 5 × 30 10 = 23 \text{均值} = \frac{2\times10 + 3\times20 + 5\times30}{10} = 23 均值=102×10+3×20+5×30=23
  • 适用场景:原始数据不可得,数据已分组。
  • 优缺点:近似计算,精度略低。
【例子与代码】

(1)生活化例子:

某公司员工工资分为三档:

  • 3000-5000元(组中值4000元),有10人
  • 5001-8000元(组中值6500元),有20人
  • 8001-15000元(组中值11500元),有5人

用分组均值公式:

  • 总工资:
    10 × 4000 + 20 × 6500 + 5 × 11500 = 40000 + 130000 + 57500 = 227500 10 \times 4000 + 20 \times 6500 + 5 \times 11500 = 40000 + 130000 + 57500 = 227500 10×4000+20×6500+5×11500=40000+130000+57500=227500
  • 总人数 = 10 + 20 + 5 = 35
  • 平均工资 ≈ 227500 / 35 ≈ 6500元

(2)Python代码实现:

import numpy as np
mid_values = np.array([4000, 6500, 11500])
counts = np.array([10, 20, 5])
mean_grouped = np.sum(mid_values * counts) / np.sum(counts)
print('分组均值:', mean_grouped)

输出:

分组均值: 6500.0

2.3 加权平均数

  • 定义:不同数据有不同权重时使用。
  • 公式
    x ˉ w = ∑ i = 1 n w i x i ∑ i = 1 n w i \bar{x}_w = \frac{\sum_{i=1}^n w_i x_i}{\sum_{i=1}^n w_i} xˉw=i=1nwii=1nwixi
  • 举例:计算不同班级人数加权的平均分。
【例子与代码】

(1)生活化例子:

有两个班级,A班有30人,平均分80分;B班有50人,平均分70分。全体学生的加权平均分是多少?

  • 总分:
    30 × 80 + 50 × 70 = 2400 + 3500 = 5900 30 \times 80 + 50 \times 70 = 2400 + 3500 = 5900 30×80+50×70=2400+3500=5900
  • 总人数 = 30 + 50 = 80
  • 加权平均分 = 5900 / 80 = 73.75分

(2)Python代码实现:

import numpy as np
scores = np.array([80, 70])
weights = np.array([30, 50])
weighted_mean = np.average(scores, weights=weights)
print('加权平均分:', weighted_mean)

输出:

加权平均分: 73.75

2.4 调和平均数

  • 定义:用于"平均速度""平均单价"等倒数关系场景。
  • 公式
    H = n ∑ i = 1 n 1 x i H = \frac{n}{\sum_{i=1}^n \frac{1}{x_i}} H=i=1nxi1n
  • 适用场景:如平均速度、平均每单位成本。
  • 举例:一段路程一半以60km/h,一半以40km/h,平均速度不是(60+40)/2,而是调和平均数。
【例子与代码】

(1)生活化例子:

你开车去外婆家,去程一半路程以60km/h,另一半以40km/h。问全程的平均速度是多少?

  • 普通平均数:(60+40)/2=50km/h(错误)
  • 调和平均数:
    2 1 60 + 1 40 = 2 5 240 = 48 km/h \frac{2}{\frac{1}{60} + \frac{1}{40}} = \frac{2}{\frac{5}{240}} = 48 \text{km/h} 601+4012=24052=48km/h

(2)Python代码实现:

import numpy as np
speeds = np.array([60, 40])
harmonic_mean = len(speeds) / np.sum(1/speeds)
print('调和平均速度:', harmonic_mean)

输出:

调和平均速度: 48.0

2.5 几何平均数

  • 定义:用于增长率、比率等场景。
  • 公式
    G = x 1 × x 2 × ⋯ × x n n G = \sqrt[n]{x_1 \times x_2 \times \cdots \times x_n} G=nx1×x2××xn
  • 适用场景:年均增长率、投资收益率等。
  • 举例:三年增长率分别为10%、20%、30%,则几何平均增长率为
    几何平均增长率 = ( 1.1 × 1.2 × 1.3 ) 1 / 3 − 1 ≈ 0.197 ≈ 19.7 % \text{几何平均增长率} = (1.1 \times 1.2 \times 1.3)^{1/3} - 1 \approx 0.197 \approx 19.7\% 几何平均增长率=(1.1×1.2×1.3)1/310.19719.7%
【例子与代码】

(1)生活化例子:

你投资理财,三年收益率分别为10%、20%、30%。问三年平均每年增长率是多少?

  • 先转为增长因子:1.1, 1.2, 1.3
  • 几何平均增长率:
    几何平均增长率 = ( 1.1 × 1.2 × 1.3 ) 1 / 3 − 1 ≈ 0.197 ≈ 19.7 % \text{几何平均增长率} = (1.1 \times 1.2 \times 1.3)^{1/3} - 1 \approx 0.197 \approx 19.7\% 几何平均增长率=(1.1×1.2×1.3)1/310.19719.7%

(2)Python代码实现:

import numpy as np
rates = np.array([1.1, 1.2, 1.3])
geometric_mean = np.prod(rates) ** (1/len(rates))
print('几何平均增长率:', geometric_mean - 1)

输出:

几何平均增长率: 0.197

3. 中位数:不怕"土豪"搅局的中心

3.1 中位数(非分组数据)

  • 定义:把数据从小到大排好,正中间的那个数。
  • 公式
    • n n n 为奇数,中位数为第 n + 1 2 \frac{n+1}{2} 2n+1 个数
    • n n n 为偶数,中位数为第 n 2 \frac{n}{2} 2n n 2 + 1 \frac{n}{2}+1 2n+1 个数的平均值
  • 举例:数据[2, 3, 5, 7, 9],中位数为5。
  • 适用场景:原始数据已知。
  • 优缺点:不受极端值影响,适合偏态分布数据。
  • 注意:中位数不能反映数据的全部信息。
【例子与代码】

(1)生活化例子:

假设你和4个朋友的月工资分别是5000、6000、7000、8000、20000元。中位数是多少?

  • 排序后:[5000, 6000, 7000, 8000, 20000]
  • 人数为5(奇数),中位数是第3个数:7000元

如果人数为偶数,比如工资为[5000, 6000, 7000, 8000],中位数是(6000+7000)/2=6500元。

(2)Python代码实现:

import numpy as np
salaries = np.array([5000, 6000, 7000, 8000, 20000])
print('中位数:', np.median(salaries))

输出:

中位数: 7000.0

3.2 中位数(分组数据)

  • 定义:数据已分组时,用累计频数法定位中位数组。
  • 公式
    M e = L + N 2 − F f × w Me = L + \frac{\frac{N}{2} - F}{f} \times w Me=L+f2NF×w
    其中:
    • L L L:中位数组下限
    • N N N:总频数
    • F F F:中位数组之前各组频数之和
    • f f f:中位数组频数
    • w w w:组距
  • 举例:累计频数到第3组超过总人数一半,则第3组为中位数组。
  • 适用场景:原始数据不可得,数据已分组。
  • 优缺点:近似计算,精度略低。
  • 注意:分组数据中位数不能直接取组中值。
【例子与代码】

(1)生活化例子:

某公司35名员工工资分为三档:

  • 3000-5000元(10人)
  • 5001-8000元(20人)
  • 8001-15000元(5人)

累计频数:

  • 第一组:10
  • 第二组:10+20=30
  • 第三组:35

总人数N=35,N/2=17.5,落在第二组。

  • 第二组下限L=5001
  • F=10(前一组累计频数)
  • f=20(中位数组频数)
  • w=8000-5001+1=3000(组距,实际可按区间)

中位数 = 5001 + 17.5 − 10 20 × 3000 ≈ 5001 + 0.375 × 3000 ≈ 6126.0 中位数 = 5001 + \frac{17.5-10}{20} \times 3000 \approx 5001 + 0.375 \times 3000 \approx 6126.0 中位数=5001+2017.510×30005001+0.375×30006126.0
注意一下:这里由于分组的下限是5001,统计学中,分组一般是左开右闭区间,所以如果在习题中,看见第二组为(5000,8000],那么此时的下限就应该是5000,公式改为:
中位数 = 5000 + 17.5 − 10 20 × 3000 ≈ 5000 + 0.375 × 3000 ≈ 6125.0 中位数 = 5000 + \frac{17.5-10}{20} \times 3000 \approx 5000 + 0.375 \times 3000 \approx 6125.0 中位数=5000+2017.510×30005000+0.375×30006125.0

(2)Python代码实现:

import numpy as np# 分组区间及频数(左开右闭)
bins = [3000, 5000, 8000, 15000]  # 分组边界
freqs = [10, 20, 5]               # 各组频数# 总人数
N = sum(freqs)
# 中位数位置
N2 = N / 2# 累计频数
cum_freqs = np.cumsum(freqs)
# 找到中位数组
for i, cf in enumerate(cum_freqs):if cf >= N2:median_group = ibreakL = bins[median_group]  # 中位数组下限
F = cum_freqs[median_group - 1] if median_group > 0 else 0  # 中位数组前累计频数
f = freqs[median_group]  # 中位数组频数
w = bins[median_group + 1] - bins[median_group]  # 组距median = L + (N2 - F) / f * w
print('分组中位数:', median)

输出:

分组中位数: 6125.0

4. 众数:最常见的"主流"

4.1 众数(非分组数据)

  • 定义:数据中出现频率最高的数值。
  • 举例:一群人最常见的鞋码。
  • 适用场景:定性数据、分类型数据。
  • 优缺点:直观,适合分类数据。有时无众数或有多个众数。
  • 注意:众数不是"最大值",有的数据没有众数。
【例子与代码】

(1)生活化例子:

假设10个人的鞋码分别为[38, 39, 40, 39, 41, 39, 40, 42, 39, 40],最常见的鞋码是多少?

  • 统计每个鞋码出现次数:39号出现4次,是众数。

(2)Python代码实现:

import numpy as np
from scipy import stats
sizes = np.array([38, 39, 40, 39, 41, 39, 40, 42, 39, 40])
mode = stats.mode(sizes, keepdims=True)[0][0]
print('最常见的鞋码(众数):', mode)

输出:

最常见的鞋码(众数): 39

4.2 众数(分组数据)

  • 公式
    M o = L + f 1 − f 0 2 f 1 − f 0 − f 2 × w Mo = L + \frac{f_1 - f_0}{2f_1 - f_0 - f_2} \times w Mo=L+2f1f0f2f1f0×w
    其中:
    • L L L:众数组下限
    • f 1 f_1 f1:众数组频数
    • f 0 f_0 f0:众数组前一组频数
    • f 2 f_2 f2:众数组后一组频数
    • w w w:组距
  • 举例:第2组频数最大,前一组频数为3,当前为8,后一组为5,组距为10,则 M o = 10 + 8 − 3 2 × 8 − 3 − 5 × 10 Mo=10+\frac{8-3}{2 \times 8-3-5} \times 10 Mo=10+2×83583×10
  • 适用场景:分组数据。
  • 注意:众数不一定唯一。
【例子与代码】

(1)生活化例子:

某班学生身高分组如下:

  • 160-165cm(3人)
  • 165-170cm(8人)
  • 170-175cm(5人)

众数组是165-170cm,频数最大。

  • L=165
  • f1=8
  • f0=3
  • f2=5
  • w=5
    众数 = 165 + 8 − 3 2 × 8 − 3 − 5 × 5 = 165 + 5 8 × 5 ≈ 168.1 众数 = 165 + \frac{8-3}{2\times8-3-5} \times 5 = 165 + \frac{5}{8} \times 5 \approx 168.1 众数=165+2×83583×5=165+85×5168.1

(2)Python代码实现:

import numpy as np# 分组区间及频数(左开右闭)
bins = [160, 165, 170, 175]  # 分组边界
freqs = [3, 8, 5]            # 各组频数# 找到众数组(频数最大组)
mode_group = np.argmax(freqs)L = bins[mode_group]  # 众数组下限
f1 = freqs[mode_group]  # 众数组频数
f0 = freqs[mode_group - 1] if mode_group > 0 else 0  # 前一组频数
f2 = freqs[mode_group + 1] if mode_group < len(freqs) - 1 else 0  # 后一组频数
w = bins[mode_group + 1] - bins[mode_group]  # 组距mode = L + (f1 - f0) / (2 * f1 - f0 - f2) * w
print('分组众数:', mode)

输出:

分组众数: 168.125

5. 分位数、四分位数、百分位数:数据的"分界线"

  • 定义:把数据分成若干等份,常用的有四分位数(Q1、Q2、Q3),Q2其实就是中位数。
  • 公式
    • Q 1 Q_1 Q1:第25%位置的数
    • Q 2 Q_2 Q2:第50%位置的数(即中位数)
    • Q 3 Q_3 Q3:第75%位置的数
    • P k P_k Pk:第 k k k百分位数, k ∈ [ 1 , 99 ] k\in[1,99] k[1,99]
  • 分组数据的分位数公式
    Q p = L + p N − F f × w Q_p = L + \frac{pN - F}{f} \times w Qp=L+fpNF×w
    其中 p p p 为分位点比例(如0.25, 0.5, 0.75),其余同中位数。
  • 举例:求第90百分位数, p = 0.9 p=0.9 p=0.9,代入公式。
  • 实际应用:高考分数线、收入分布、身高体重的分级等。
  • 优缺点:抗极端值能力强,能反映分布的不同区间。
  • 注意:百分位数不是百分比,分位数位置要用累计频数法定位。
【例子与代码】

(1)生活化例子:

某班10名学生成绩:[65, 70, 72, 75, 78, 80, 82, 85, 90, 95]

  • Q1(25%分位数)=72.75
  • Q2(50%分位数/中位数)=79
  • Q3(75%分位数)=84.25
  • 第90百分位数P90=90.5

(2)Python代码实现:

import numpy as np
scores = np.array([65, 70, 72, 75, 78, 80, 82, 85, 90, 95])
q1 = np.percentile(scores, 25)
q2 = np.percentile(scores, 50)
q3 = np.percentile(scores, 75)
p90 = np.percentile(scores, 90)
print('Q1:', q1, 'Q2:', q2, 'Q3:', q3, 'P90:', p90)

输出:

Q1: 72.75 Q2: 79.0 Q3: 84.25 P90: 90.5

6. 极值与极差:数据的"边界"

  • 极大值 x max ⁡ x_{\max} xmax,极小值: x min ⁡ x_{\min} xmin
  • 范围(极差)
    R = x max ⁡ − x min ⁡ R = x_{\max} - x_{\min} R=xmaxxmin
  • 举例:最大分95,最小分65,极差30。
  • 实际意义:极差能快速反映数据的跨度,但对极端值极其敏感。
  • 注意:极差大不代表数据分布一定分散,可能只是有极端值。
【例子与代码】

(1)生活化例子:

某班10名学生成绩:[65, 70, 72, 75, 78, 80, 82, 85, 90, 95]

  • 最大值=95,最小值=65,极差=95-65=30

(2)Python代码实现:

import numpy as np
scores = np.array([65, 70, 72, 75, 78, 80, 82, 85, 90, 95])
print('最大值:', np.max(scores))
print('最小值:', np.min(scores))
print('极差:', np.ptp(scores))

输出:

最大值: 95
最小值: 65
极差: 30

7. 离散程度统计量:数据"散不散"?

7.1 极差

  • 最大值-最小值,反映数据的跨度。
【例子与代码】

(1)生活化例子:

某班成绩:[65, 70, 72, 75, 78, 80, 82, 85, 90, 95],极差=95-65=30。

(2)Python代码实现:

import numpy as np
scores = np.array([65, 70, 72, 75, 78, 80, 82, 85, 90, 95])
print('极差:', np.ptp(scores))

输出:

极差: 30

7.2 四分位距(IQR)

  • Q3-Q1,反映中间50%数据的分布范围,抗极端值能力强。
【例子与代码】

(1)生活化例子:

同样成绩,Q3=84.25,Q1=72.75,IQR=84.25-72.75=11.5。

(2)Python代码实现:

import numpy as np
from scipy import stats
scores = np.array([65, 70, 72, 75, 78, 80, 82, 85, 90, 95])
print('IQR:', stats.iqr(scores))

输出:

IQR: 11.5

7.3 方差

  • 每个数据与均值的差的平方的平均值,反映数据波动大小。
  • 公式
    s 2 = 1 n − 1 ∑ i = 1 n ( x i − x ˉ ) 2 s^2 = \frac{1}{n-1} \sum_{i=1}^n (x_i - \bar{x})^2 s2=n11i=1n(xixˉ)2
  • 分组数据的方差公式
    s 2 = ∑ i = 1 k f i ( m i − x ˉ ) 2 N − 1 s^2 = \frac{\sum_{i=1}^k f_i (m_i - \bar{x})^2}{N-1} s2=N1i=1kfi(mixˉ)2
  • 举例:三组组中值10、20、30,频数2、3、5,均值23,则方差 = 2 × ( 10 − 23 ) 2 + 3 × ( 20 − 23 ) 2 + 5 × ( 30 − 23 ) 2 10 − 1 =\frac{2 \times (10-23)^2+3\times (20-23)^2+5\times(30-23)^2}{10-1} =1012×(1023)2+3×(2023)2+5×(3023)2
  • 实际意义:方差越大,数据波动越大。
【例子与代码】

(1)生活化例子:

同样成绩,方差=每个分数与均值差的平方的平均值(无偏估计用n-1)。

(2)Python代码实现:

import numpy as np
scores = np.array([65, 70, 72, 75, 78, 80, 82, 85, 90, 95])
print('方差:', np.var(scores, ddof=1))

输出:

方差: 85.06666666666666

7.4 标准差

  • 方差的平方根,单位和原数据一样,更直观。
  • 实际意义:标准差越大,数据越分散。标准差为0,说明所有数据都一样。
  • 生活化案例:比如班级成绩标准差大,说明成绩差异大。
  • 注意:标准差不是越小越好,要结合实际场景。
【例子与代码】

(1)生活化例子:

同样成绩,标准差=方差的平方根。

(2)Python代码实现:

import numpy as np
scores = np.array([65, 70, 72, 75, 78, 80, 82, 85, 90, 95])
print('标准差:', np.std(scores, ddof=1))

输出:

标准差: 9.223159256278006

7.5 变异系数

  • 标准差/均值,适合比较不同量纲的数据波动性。
  • 公式
    C V = s x ˉ CV = \frac{s}{\bar{x}} CV=xˉs
  • 实际意义:无量纲,便于不同单位、不同均值的数据比较。
  • 举例:比较身高和体重的离散程度。
  • 注意:均值为0时不能用变异系数。
【例子与代码】

(1)生活化例子:

同样成绩,标准差/均值=9.5/79.2≈0.116。

(2)Python代码实现:

import numpy as np
scores = np.array([65, 70, 72, 75, 78, 80, 82, 85, 90, 95])
cv = np.std(scores, ddof=1) / np.mean(scores)
print('变异系数:', cv)

输出:

变异系数: 0.11645403101361118

8. 形态统计量:数据"长什么样"?

8.1 偏度(偏态分布)

  • 衡量数据分布是否对称。偏度>0,右偏(长尾在右);偏度<0,左偏。
  • 公式
    S k e w n e s s = 1 n ∑ i = 1 n ( x i − x ˉ ) 3 s 3 Skewness = \frac{\frac{1}{n} \sum_{i=1}^n (x_i - \bar{x})^3}{s^3} Skewness=s3n1i=1n(xixˉ)3
  • 实际意义
    • 右偏(正偏):均值 > 中位数 > 众数,数据向左集中,右侧有长尾。
    • 左偏(负偏):众数 > 中位数 > 均值,数据向右集中,左侧有长尾。
  • 生活化案例:收入分布通常右偏,大多数人收入低于均值。
  • 可视化演示

左右偏态分布示意图

  • 图解说明
    • 右偏分布:红线(均值)> 绿线(中位数)> 蓝线(众数)
    • 左偏分布:蓝线(众数)> 绿线(中位数)> 红线(均值)
    • 右偏常见于收入、房价等数据,左偏常见于老年人去世年龄分布(大部分人寿命较长,少数人早逝)。
  • 注意:偏度大不代表数据异常,只是分布不对称。
【例子与代码】

(1)生活化例子:

某公司10名员工工资:[3000, 3200, 3500, 4000, 4200, 4500, 5000, 6000, 8000, 20000]

  • 绝大多数工资集中在5000以下,只有一个人特别高,分布右偏。

(2)Python代码实现:

import numpy as np
from scipy import stats
salaries = np.array([3000, 3200, 3500, 4000, 4200, 4500, 5000, 6000, 8000, 20000])
skewness = stats.skew(salaries)
print('偏度:', skewness)

输出:

偏度: 2.2804665912927278

8.2 峰度

  • 衡量分布"尖不尖"。峰度高,分布陡峭;峰度低,分布平坦。
  • 公式
    K u r t o s i s = 1 n ∑ i = 1 n ( x i − x ˉ ) 4 s 4 − 3 Kurtosis = \frac{\frac{1}{n} \sum_{i=1}^n (x_i - \bar{x})^4}{s^4} - 3 Kurtosis=s4n1i=1n(xixˉ)43
  • 实际意义:判断分布是否有"厚尾"或"尖峰"。
  • 注意:对极端值敏感,解释需结合实际。
【例子与代码】

(1)生活化例子:

同样工资数据,峰度反映分布是否有尖峰或厚尾。

(2)Python代码实现:

import numpy as np
from scipy import stats
salaries = np.array([3000, 3200, 3500, 4000, 4200, 4500, 5000, 6000, 8000, 20000])
kurt = stats.kurtosis(salaries)
print('峰度:', kurt)

输出:

峰度: 3.825791712058331

9. 频数与频率统计量:数据的"热度榜"

  • 频数:某个数出现的次数
  • 频率:某个数出现的比例
  • 累计频数/频率:小于等于某值的累计次数/比例
  • 公式
    • 频数 $f_i $:第 i i i 类别出现的次数
    • 频率 p i p_i pi p i = f i n p_i = \frac{f_i}{n} pi=nfi
    • 累计频数/频率:前 i i i 类别的频数/频率之和
  • 累计频率曲线:以横轴为数据值,纵轴为累计频率,画出曲线,常用于分布特征直观展示。
  • 举例:分组累计频数定位分位点。
  • 适用场景:分类数据、分组数据、分布特征展示
  • 注意:累计频率不是概率分布,累计频数定位分位点需精确
【例子与代码】

(1)生活化例子:

10名同学喜欢的水果:[‘苹果’, ‘香蕉’, ‘苹果’, ‘橙子’, ‘香蕉’, ‘苹果’, ‘葡萄’, ‘香蕉’, ‘苹果’, ‘橙子’]

  • 频数:苹果4,香蕉3,橙子2,葡萄1
  • 频率:苹果40%,香蕉30%,橙子20%,葡萄10%

(2)Python代码实现:

import pandas as pd
fruits = ['苹果', '香蕉', '苹果', '橙子', '香蕉', '苹果', '葡萄', '香蕉', '苹果', '橙子']
s = pd.Series(fruits)
counts = s.value_counts()
freq = s.value_counts(normalize=True)
print('频数:')
print(counts)
print('频率:')
print(freq)

输出:

频数:
苹果    4
香蕉    3
橙子    2
葡萄    1
Name: count, dtype: int64
频率:
苹果    0.4
香蕉    0.3
橙子    0.2
葡萄    0.1
Name: count, dtype: float64

10. 生活化案例:小班成绩分析

假设有10个同学的数学成绩如下:

[65, 70, 72, 75, 78, 80, 82, 85, 90, 95]

我们来用各种统计量描述这组数据:

  • 📊 均值:79.2分
  • 📈 中位数:79分(第5和第6个数的平均)
  • 🥇 众数:无(每个分数只出现一次)
  • 📏 极差:95-65=30分
  • 🟩 四分位数:Q1=72.75,Q2=79,Q3=84.25
  • 🟦 IQR:84.25-72.75=11.5分
  • 🧮 方差/标准差:约85.07/9.2
  • 🔀 偏度/峰度: 0.1986/-0.8172

11. 动手试试:用代码说话

import numpy as np
from scipy import statsscores = np.array([65, 70, 72, 75, 78, 80, 82, 85, 90, 95])print('均值:', np.mean(scores))
print('中位数:', np.median(scores))
print('众数:', stats.mode(scores, keepdims=True)[0][0])
print('极差:', np.ptp(scores))
print('方差:', np.var(scores, ddof=1))
print('标准差:', np.std(scores, ddof=1))
print('四分位数:', np.percentile(scores, [25, 50, 75]))
print('IQR:', stats.iqr(scores))
print('偏度:', stats.skew(scores))
print('峰度:', stats.kurtosis(scores))

12. 别被这些误区骗了

❌ 误区1:平均数就是"典型水平"

真相:极端值会让平均数失真,中位数或众数有时更靠谱。

❌ 误区2:标准差越小越好

真相:要结合实际场景,有时分散反而是好事。

举个例子:

比如在投资理财中,如果你的投资组合里既有稳健型资产(收益波动小),也有高风险高收益的资产(收益波动大),整体收益的标准差就会比单一资产大一些。这种"分散"有时是好事,因为它意味着你有机会获得更高的收益,而不是所有资产都表现平平。如果所有资产收益都一样(标准差为0),反而缺乏增长动力。

❌ 误区3:众数一定存在

真相:有的数据没有众数,或有多个众数。

❌ 误区4:极差越大数据越分散

真相:可能只是有极端值。

❌ 误区5:分组数据的中位数/众数可以直接取组中值

真相:必须用公式推算。


13. 重点回顾

✅ 描述性统计是数据分析的第一步,帮我们快速了解数据特征

✅ 常见统计量分为位置、离散、形态三类

✅ 每个统计量有适用场景和局限性,不能机械套用

✅ 生活中很多"平均数"其实并不代表大多数人


14. 练习一下

基础题

  1. 用自己的话解释均值、中位数、众数的区别。
  2. 什么时候用中位数比均值更合适?
  3. 极差和IQR分别适合什么场景?

思考题

  1. 某公司10名员工工资分别为[3000, 3200, 3500, 4000, 4200, 4500, 5000, 6000, 8000, 20000],你觉得用哪个统计量描述"典型工资"最合适?为什么?
  2. 某班数学成绩标准差为0,说明了什么?

动手题

  1. 用代码算出上面成绩的偏度和峰度,并解释结果。
  2. 试着用自己的数据,算一算均值、中位数、众数、极差、标准差。

15. 下期预告

下一篇我们聊"数据可视化:一图胜千言",会带你用各种图表把数据讲清楚,敬请期待!


📚 参考资料

  • 吴喜之著《统计学:从数据到结论》,中国统计出版社
  • 盛骤等著《概率论与数理统计》,高等教育出版社
  • 作者个人学习和实践经验总结

写在最后:如果你觉得这篇文章对你有帮助,欢迎点赞、收藏和分享!有任何问题或建议,欢迎在评论区留言交流,我会认真回复每一条评论。让我们一起用统计学的眼光看世界,一起进步!📊

http://www.xdnf.cn/news/767485.html

相关文章:

  • Figma 与 Cursor 深度集成的完整解决方案
  • 【数据分析】第四章 pandas简介(1)
  • Caliper压力测试
  • mac安装brew时macos无法信任ruby的解决方法
  • 智慧零工平台后端开发实战:Spring Boot 3 + MyBatis-Flex 现代化架构
  • Linux中的mysql备份与恢复
  • Unity + HybirdCLR热更新 入门篇
  • GStreamer开发笔记(六):gstreamer基本概念:组件、箱柜、管道、衬垫、链接组件
  • 【端午安康】龙舟争渡Plug-In
  • 计算机组成原理核心剖析:CPU、存储、I/O 与总线系统全解
  • 空调清洗教程
  • Python----目标检测(《YOLOv3:AnIncrementalImprovement》和YOLO-V3的原理与网络结构)
  • 20250602在Ubuntu20.04.6下修改压缩包的日期和时间
  • 分布式锁优化:使用Lua脚本保证释放锁的原子性问题
  • SQL进阶之旅 Day 12:分组聚合与HAVING高效应用
  • 微服务-Sentinel
  • Oracle expdp过滤部分表数据
  • vue-12 (路由守卫:全局、每个路由和组件内)
  • 【Unity】相机 Cameras
  • 项目管理进阶:56页大型IT项目管理实践经验分享【附全文阅读】
  • 数据库系统概论(十四)详细讲解SQL中空值的处理
  • Leetcode 2123. 使矩阵中的 1 互不相邻的最小操作数
  • 数据结构之堆:解析与应用
  • 高阶数据结构——并查集
  • vscode 插件 eslint, 检查 js 语法
  • mysql分布式教程
  • 构建高性能风控指标系统
  • AIGC工具平台-GPT-SoVITS-v4-TTS音频推理克隆
  • Arbitrum Stylus 合约实战 :Rust 实现 ERC721
  • Windows 账号管理与安全指南