常用的描述性统计指标Python实现
生成一些数据
使用list,numpy的ndarray、pandas的Series/dataframe来生成一些示例数据
import numpy as np
import pandas as pd
from numpy.random import normal,randint
# 使用list来创造一组数据
data1 = [1,2,3]
# 使用ndarray来创造一组数据
data2 = np.array([1,2,3])
# 使用series来创造一组数据
data3 = pd.Series([1,2,3])
# 使用一组服从正态分布的数值型数据
data4 = normal(0,10,size = 10)
#创造一组服从均匀分布的分类数据(size表示生成的元素个数),前两个参数表示范围:左闭右开
data5 = randint(0,10,size = 10)
print('data1:\n',data1,'\ndata2:\n',data2,'\ndata3:\n',data3,'\ndata4:\n',data4,'\ndata5:\n',data5)
data1:
[1, 2, 3]
data2:
[1 2 3]
data3:
0 1
1 2
2 3
dtype: int64
data4:
[-11.05791317 -1.277683 2.90156063 -5.30614673 -3.09032682
-0.99253227 -0.86960447 2.65545431 -6.7752268 1.64985895]
data5:
[8 3 7 5 6 6 3 2 2 3]
集中趋势描述:均值、中位数、众数的实现
均值
$$\mu=\frac{\displaystyle\sum\limits_{i=1}^N{X_i}}{N}$$
import numpy as np
import pandas as pd
from numpy.random import normal,randint
# 计算均值--numpy实现
print(np.mean(data4))
#计算均值--自编实现
def cal_mean(nums):
return sum(nums)/len(nums)
cal_mean(data4)
#计算中位数--numpy实现
print(np.median(data5))
#计算中位数--自编实现
def cal_median(nums):
length = len(nums)
sorted_nums = sorted(nums) #默认是升序排列
if length % 2:
return sorted_nums[length//2]
else:
return(sorted_nums[length//2+1]+sorted_nums[length//2])/2
cal_median(data5)
#计算众数——只返回一个众数即可
## 1) 先将每个值按照从小到大的连续顺序,对应在数组中出现的次数算出来
##np.bincount方法返回了一个长度为data5最大值的列表,列表中的每个值代表其索引位数值出现在data5中的次数,例如
##返回[2,1,0],代表0在data5中出现2次,而1在data5中出现1次,3在data5中没有出现
print(data5)
counts = np.bincount(data5)
print(counts)
## 2) 返回众数
idx = np.argmax(counts)
print(idx)
#计算众数——众数的另一种实现方式(推荐方法)--使用scipy
##上一种方法有至少两个缺点:1、由于索引值都是从0开始,故只能用于非负数据集;2、浮点型数据不支持np.bincount()
from scipy import stats
print(stats.mode(data5)[0][0])
-2.2162559377648825
4.0
[8 3 7 5 6 6 3 2 2 3]
[0 0 2 3 0 1 2 1 1]
3
3
离散程度描述:极差、方差、标准差、变异系数的实现
极差
$$R=\max{(X)}-\min{(X)}$$
方差
$$\sigma^2=\frac{\displaystyle\sum\limits_{i=1}^N (X_i-\mu)^2}{N}$$
标准差
$$\sigma=\sqrt{\sigma^2}$$
变异系数
$$CV=\frac{\sigma}{\mu}$$
# 计算极差--自编实现
def cal_ptp(nums):
return max(nums)-min(nums)
cal_ptp(data4)
# 计算极差—numpy实现
np.ptp(data4)
#计算方差--自编实现
def cal_var(nums):
nums_mean = cal_mean(nums)
res = 0
for num in nums:
res +=(num-nums_mean)**2
res = res/len(nums)
return res
cal_var(data4)
#计算方差--numpy实现
np.var(data4)
#计算标准差--自编实现
def cal_std(nums):
return cal_var(nums)**0.5
cal_std(data4)
#计算标准差--numpy实现
np.std(data4)
#计算变异系数--自编实现
def cal_cv(nums):
return cal_std(nums)/cal_mean(nums)
cal_cv(data4)
#计算变异系数--numpy实现
np.std(data4)/ np.mean(data4)
-1.905452991162375
偏差程度:Z-分数
$$Z_i=\frac{X_i-\mu}{\sigma}$$
# 计算data4数据中的第一个值的Z-分数
print((data4[0]-np.mean(data4))/np.std(data4))
#array一组数同时进行计算Z-分数
(data4 - np.mean(data4))/np.std(data4)
-2.093705161018736
array([-2.09370516, 0.22225415, 1.21189938, -0.73168639, -0.20698006,
0.28977787, 0.31888718, 1.15362139, -1.07956468, 0.91549632])
相关程度:协方差、相关系数
协方差
$$Cov(X,Y)=\frac{\displaystyle\sum\limits_{i=1}^N (X_i-\bar{X})(Y_i-\bar{Y})}{N}$$
相关系数
$$r(X,Y)=\frac{Cov(X,Y)}{\sigma_X \sigma_Y}$$
data = np.array([data4,data5])
print(data)
#计算协方差--自编实现
def cal_cov(nums_matrix):
length = len(nums_matrix)
res = [[0 for _ in range(length)] for _ in range(length)] # 列表生成式,嵌套列表
for m in range(length):
for n in range(length):
res[m][n] = sum([(x - cal_mean(nums_matrix[m]))*(y - cal_mean(nums_matrix[n])) for x,y in zip(nums_matrix[m],nums_matrix[n])])/len(nums_matrix[m])
return np.array(res)
print(cal_cov(data))
# 计算协方差--使用numpy实现
# 参数bias = 1表示结果需要除以N(默认是除以(N-1))
# 返回结果为矩阵,第i行第j列的数据表示第i组数与第j组数的协方差,对角线为方差
data = np.array([data4,data5])
np.cov(data,bias = 1)
# 计算相关系数--自编实现
def cal_corr(nums_matrix):
length = len(nums_matrix)
res = cal_cov(nums_matrix)
for m in range(length):
for n in range(length):
res[m][n] = res[m][n]/(cal_std(nums_matrix[m])*cal_std(nums_matrix[n]))
return res
cal_corr(data)
#计算相关系数--numpy实现
np.corrcoef(data)
[[-11.05791317 -1.277683 2.90156063 -5.30614673 -3.09032682
-0.99253227 -0.86960447 2.65545431 -6.7752268 1.64985895]
[ 8. 3. 7. 5. 6.
6. 3. 2. 2. 3. ]]
[[17.83348834 -2.91805825]
[-2.91805825 4.25 ]]
array([[ 1. , -0.3351825],
[-0.3351825, 1. ]])
pandas表格概括性统计描述
#生成数据
table_df = pd.DataFrame({
'收入':[np.nan,10008.5,8550.0,3331.3,15920.0],
'性别':['男','女','女','男','女'],
'年龄':[24,28,25,20,27],
'职业':['公务员','数据分析师','审计','收银员','数据分析师']
})
table_df
收入 性别 年龄 职业 0 NaN 男 24 公务员 1 10008.5 女 28 数据分析师 2 8550.0 女 25 审计 3 3331.3 男 20 收银员 4 15920.0 女 27 数据分析师
# 查看表格的概括性描述(默认只有数值型变量列的描述)
table_df.describe()
收入 年龄 count 4.000000 5.000000 mean 9452.450000 24.800000 std 5177.556951 3.114482 min 3331.300000 20.000000 25% 7245.325000 24.000000 50% 9279.250000 25.000000 75% 11486.375000 27.000000 max 15920.000000 28.000000
# 查看表格所有列的概括性描述
table_df.describe(include = 'all')
收入 性别 年龄 职业 count 4.000000 5 5.000000 5 unique NaN 2 NaN 4 top NaN 女 NaN 数据分析师 freq NaN 3 NaN 2 mean 9452.450000 NaN 24.800000 NaN std 5177.556951 NaN 3.114482 NaN min 3331.300000 NaN 20.000000 NaN 25% 7245.325000 NaN 24.000000 NaN 50% 9279.250000 NaN 25.000000 NaN 75% 11486.375000 NaN 27.000000 NaN max 15920.000000 NaN 28.000000 NaN
#查看各列的数据类型
table_df.dtypes
收入 float64
性别 object
年龄 int64
职业 object
dtype: object
#查看类别变量列的描述信息
table_df.describe(include = 'object')
性别 职业 count 5 5 unique 2 4 top 女 数据分析师 freq 3 2