描述性统计所提取统计的信息,我们称为统计量,主要包括以下⼏个⽅⾯:
频数与频率
频数
指次数
频率
指每个变量的频数与总次数的比值,一般用百分比表示。
import collections
data = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5]
# 计算频数
frequency_counter = collections.Counter(data)
# print(frequency_counter)
# 打印频数
print("频数:")
for value,count in frequency_counter.items():
print(f"{value}:{count}")
# 计算总数
total_count = len(data)
# 计算频率
frequency_dict = {value: count/total_count for value,count in frequency_counter.items()}
# 打印频率
print("\n频率:")
for value,freq in frequency_dict.items():
print(f"{value}:{freq:.2%}")
运行结果
频数:
1:1
2:2
3:3
4:4
5:5频率:
1:6.67%
2:13.33%
3:20.00%
4:26.67%
5:33.33%
集中趋势分析
均值
元素的算术平均值
中位数
指按顺序排列的一组数据中居于中间位置的数。如果总长度为偶数,中位数是中间两个数的算术平均值。
众数
指一组数据中出现次数或出现频率最多的数值,它是一种位置平均数,不受极端变量值的影响。众数主要用于测度分类数据的集中趋势,也可以用来测度顺序数据和数值型数据的集中趋势。
分位数
指将一个随机变量的概率分布范围分为几个等份的数值点,常用的有中位数(即二分位数)、四分位数、百分位数等。
import numpy as np
from scipy import stats # 统计和随机数
data = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5]
# 计算均值
mean_value = np.mean(data)
print(f"均值:{mean_value}")
# 计算中位数
median_value = np.median(data)
print(f"中位数:{median_value}")
# 计算众数
mode_result = stats.mode(data)
print(f"众数: {mode_result.mode}, 出现次数: {mode_result.count}")
运行结果
均值:3.6666666666666665
中位数:4.0
众数: 5, 出现次数: 5
分位数
import numpy as np
data = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5]
# 计算第一四分位数 (Q1)
q1 = np.percentile(data,25)
print(f"第一四分位数(Q1): {q1}")
# 计算中位数 (Q2)
q2 = np.percentile(data,50)
print(f"中位数(Q2):{q2}")
# 计算第四分位数 (Q3)
q3 = np.percentile(data,75)
print(f"第三分位数(Q3):{q3}")
运行结果
第一四分位数(Q1): 3.0
中位数(Q2):4.0
第三分位数(Q3):5.0
离散程度分析
极差
最大值与最小值之间的差距,即最大值减最小值后所得之数据。
⽅差
方差是在概率论和统计方差衡量随机变量或一组数据时离散程度的度量。
标准差
标准差是方差的算术平方根。标准差能反映一个数据集的离散程度。
分布形状
偏度
偏度(skewness)是表示数据分布偏斜程度的统计量,它是描述数据分布的非对称性的指标。正偏分布(偏度>0)表示分布的尾部在右侧,负偏分布(偏度<0)表示分布的尾部在左侧,无偏分布(偏度=0)表示分布是对称的。
峰度
峰度(kurtosis)是描述分布的尖峰程度的统计量。高峰分布(峰度>0)表示分布具有比正态分布更尖锐的峰,低峰分布(峰度<0)表示分布的峰比正态分布更平坦,正常分布(峰度=0)表示分布类似于正态分布。
根据这两个指标,我们可以判断数据系列的分布是否满足正态性,进而评价平均数指标的使用价值。一般地,对于一个偏态分布、肥尾分布特征很明显的数据序列来说,平均数这个指标极易令人误解数据序列分布的集中位置及其集中程度,故此使用起来要极其谨慎。
在金融领域,偏度和峰度常用于评估资产价格和投资组合的风险和收益特征。
在人口统计学中,偏度和峰度可用于描述人口年龄分布的形状和特征。
在产品销售方面,偏度和峰度可以用于评估销售数据的非对称性和尖峰性。
import numpy as np
from scipy.stats import skew,kurtosis
data = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5]
# 计算偏度(skewness)
data_skewness = skew(data)
print(f"偏度:{data_skewness}")
# 计算峰度(kurtosis)
data_kurtosis = kurtosis(data)
print(f"峰度:{data_kurtosis}")
# 运行结果
偏度:-0.5879747322073333
峰度:-0.7285714285714295
变量的类型
类别变量
⽆序类别变量(名义变量)
指两个及以上的分类,但是本身没有等级顺序之分。
有序类别变量(等级变量)
有序变量是指分类数大于等于3,且类别之间存在序次关系的响应变量。
数值变量
连续变量
连续变量数值是连接不断的,相邻两值之间可作无限分割,例如,身高、体重、年龄等都是连续变量。年龄一般虽按整数计算,但如严格按出生时间起算,是可以细算到许多位小数的。连续变量的数值要用测量或计算的方法取得。
离散变量
离散变量的各变量值之间都是以整数断开的,如人数、工厂数、机器台数等,都只能按整数计算。离散变量的数值只能用计数的方法取得。
代码笔记:
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore') # 忽略索引 不会影响源代码的运行
# 导入数据集
iris = load_iris()
# print(iris)
# 获取data里面的数组
# print(iris.data)
# print(iris.target)
# numpy拼接 把iris.data和iris.target拼接到一起
data = np.concatenate([iris.data, iris.target.reshape(-1,1)],axis=1) # 数组拼接用concatenate 升维用reshape(-1,1)
# data转成表格形式 方便进行数据处理和分析
df = pd.DataFrame(data,columns=['sepal_length','sepal_width','petal_length','petal_width','type']) # 'type'列名
# 统计 频数
fre = df['type'].value_counts()
print("频数:",fre)
# 频率
# 方法1:
# per = fre*100/sum(fre)
# print(sum(fre))
# print(per)
# 方法2:
per = fre*100/len(df) # 分母是源数据的总长度
print("频率:", per)
# 显示中文
plt.rcParams['font.family'] = ['SimHei']
# 设置字体大小
plt.rcParams['font.size'] = 15
# 调整图像大小
plt.figure(figsize=(10,6))
# 求平均值
mean = df['sepal_length'].mean()
print("平均值",mean)
# 求中位数
median = df['sepal_length'].median()
print("中位数", median)
# 求众数
s = df['sepal_length'].mode()
print("众数", s.iloc[0]) # 通过下标取值取到5
sns.displot(df['sepal_length']) # seaborn 0.11之后的版本用histplot()
plt.axvline(mean,ls='-', color='r', label='平均值') # axvline 画垂直线
plt.axvline(median,ls='-', color='g', label='中位数')
plt.axvline(s.iloc[0],ls='-', color='b', label='众数')
plt.legend()
plt.show()
# 分位数
import numpy as np
data = np.array([1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5])
# 计算第⼀四分位数(Q1)
q1 = np.percentile(data, 25)
print(f"第⼀四分位数(Q1): {q1}")
print(np.percentile(data,q=[25,50,75]))
# pandas
#data转成series
data2 = pd.Series(data)
print(data2.describe())
print(data2.describe(percentiles=[0.25,0.9]))
# 极差
sub = np.ptp(df['sepal_length'])
# 方差
var = df['sepal_length'].var()
# 标准差
std = df['sepal_length'].std()
print(sub, var, std)
# 分布形状
plt.figure(figsize=(10,6))
t1 = np.random.randint(1, 11, size=100)
t2 = np.random.randint(11, 21, size=500)
t3 = np.concatenate([t1, t2])
skew1 = pd.Series(t3)
t1 = np.random.randint(1, 11, size=500)
t2 = np.random.randint(11, 21, size=100)
t3 = np.concatenate([t1, t2])
skew2 = pd.Series(t3)
# 计算偏度
print(skew1.skew(), skew2.skew())
# 绘图
sns.kdeplot(skew1,shade=True,label='左偏')
sns.kdeplot(skew2,shade=True,label='右偏')
plt.legend()
plt.show()
# 求峰度
print("峰度", skew1.kurt())
运行结果
频数: type
0.0 50
1.0 50
2.0 50
Name: count, dtype: int64
频率: type
0.0 33.333333
1.0 33.333333
2.0 33.333333
Name: count, dtype: float64
平均值 5.843333333333334
中位数 5.8
众数 5.0
第⼀四分位数(Q1): 3.0
[3. 4. 5.]
count 15.000000
mean 3.666667
std 1.290994
min 1.000000
25% 3.000000
50% 4.000000
75% 5.000000
max 5.000000
dtype: float64
count 15.000000
mean 3.666667
std 1.290994
min 1.000000
25% 3.000000
50% 4.000000
90% 5.000000
max 5.000000
dtype: float64
3.6000000000000005 0.6856935123042507 0.828066127977863
-0.9057070126086536 0.8604458999289398
峰度 0.26856882705244933