AI智能
改变未来

怎么样描述你的数据——用python做描述性分析

描述性统计分析是关于数据的描述和汇总。它使用两种主要方法:

  1. 定量方法以数值方式描述和汇总数据。

  2. 可视化方法通过图表,曲线图,直方图和其他图形来说明数据。

一般在数据分析的过程中,拿到数据不会去直接去建模,而是先做描述性分析来对数据有一个大致的把握,很多后续的建模方向也是通过描述性分析来进一步决定的。那么除了在Excel/R中可以去做描述性分析。

本文将细致讲解如何使用python进行描述性分析的定量分析部分:

  • 均值

  • 中位数

  • 方差

  • 标准差

  • 偏度

  • 百分位数

  • 相关性

至于可视化的部分可以参考我之前讲解pyecharts的文章,当然后面还会介绍echarts以及ggplot2的方法。

涉及到的python库

  • Python statistics是用于描述性统计信息的内置Python库。如果您的数据集不是太大,或者您不能依赖于导入其他库,则可以使用它。

  • NumPy是用于数字计算的第三方库,已针对使用一维和多维数组进行了优化。它的主要类型是称为的数组类型

    ndarray

    。该库包含许多用于统计分析的方法。

  • SciPy是基于NumPy的用于科学计算的第三方库。与NumPy相比,它提供了其他功能,包括

    scipy.stats

    统计分析。Getting started – SciPy.org

  • Pandas是基于NumPy的用于数值计算的第三方库。它擅长处理带有

    Series

    对象的带标签的一维(1D)数据和带有对象的二维(2D)数据

    DataFrame

  • Matplotlib是用于数据可视化的第三方库。通常会与NumPy,SciPy和Pandas结合使用

开始

首先导入所有的包

import math
import statistics
import numpy as np
import scipy.stats
import pandas as pd

创建数据

x

x_with_nan

都是list。不同之处在于

x_with_nan

包含一个

nan

值。也就是空值(缺失值),这样的数据在分析中十分常见。那么在python里,创建一个nan值可以有以下方法

float(\'nan\')
math.nan
np.nan

当然这三种方法创建的空值都是等价的

但是真的相等吗,两个nan是不相等的,换句话说,是不可以进行比较的,这后面的故事以后再说。

接着,我们使用numpy和pandas来创建两个一维numpy arrays和pandas series

均值

均值的定义啥的,就不说了,R里面直接mean()就可以,而在python,不导入包,怎么计算:

当然也可以用python的内置统计功能

但是如果数据中包含nan,那么将返回nan

>>> mean_ = statistics.mean(x_with_nan)
>>> mean_
nan

如果使用numpy

>>> mean_ = np.mean(y)
>>> mean_
8.7

在上面的示例中,

mean()

是一个函数,但是您也可以使用相应的方法

>>> mean_ = y.mean()
>>> mean_
8.7

如果包含nan,numpy也会返回nan,那么要是想忽略nan,可以使用np.nanmean()

>>> np.mean(y_with_nan)
nan
>>> np.nanmean(y_with_nan)
8.7

pandas也有对应方法,但是,默认情况下,

.mean()

在Pandas中忽略nan值:

mean_ = z.mean()
mean_
>>> z_with_nan.mean()
8.7

中位数

比较平均值和中位数,这是检测数据中异常值和不对称性的一种方法。平均值还是中位数对您更有用,取决于特定问题的背景。而不使用包的计算方法:

>>> n = len(x)
>>> if n % 2:
...     median_ = sorted(x)[round(0.5*(n-1))]
... else:
...     x_ord, index = sorted(x), round(0.5 * n)
...     median_ = 0.5 * (x_ord[index-1] + x_ord[index])
...
>>> median_
4

其他方法

>>> median_ = np.median(y)
>>> median_
4.0
>>> np.nanmedian(y_with_nan)
4.0

方差

方差的意义也不过多说明,在Excel中直接用stdev函数,但是怎么在python中计算?记得当初研究生复试就被问到用python不导入包怎么计算方差?

>>> n = len(x)
>>> mean_ = sum(x) / n
>>> var_ = sum((item - mean_)**2 for item in x) / (n - 1)
>>> var_
123.19999999999999

当然更简单的方法是直接使用函数,不过有nan还是会返回nan

>>> var_ = statistics.variance(x)
>>> var_
123.2
>>> statistics.variance(x_with_nan)
nan

放在numpy里面就更简单了,可以使用np.var()或者.var()

>>> var_ = np.var(y, ddof=1)
>>> var_
123.19999999999999
>>> var_ = y.var(ddof=1)
>>> var_
123.19999999999999

这里ddof就是自由度要设置为1才是无偏的。也就是分母用n-1替换n。如果有nan怎么办?返回nan,但是可以用np.nanvar()跳过nan,不过ddof依旧要设置为1

>>> np.var(y_with_nan, ddof=1)
nan
>>> y_with_nan.var(ddof=1)
nan
>>> np.nanvar(y_with_nan, ddof=1)
123.19999999999999

标准差

有了方差,标准差就很好计算了

#直接计算
>>> std_ = var_ ** 0.5
>>> std_
11.099549540409285
#使用内置包
>>> std_ = statistics.stdev(x)
>>> std_
11.099549540409287

numpy中也很好计算

>>> np.std(y, ddof=1)
11.099549540409285
>>> y.std(ddof=1)
11.099549540409285
>>> np.std(y_with_nan, ddof=1)
nan
>>> y_with_nan.std(ddof=1)
nan
>>> np.nanstd(y_with_nan, ddof=1) #跳过nan,ddof还是要是1哦
11.099549540409285

偏度(skew)

偏度(skewness)也称为偏态、偏态系数,是统计数据分布偏斜方向和程度的度量,是统计数据分布非对称程度的数字特征。偏度是利用3阶矩定义的,偏度的计算公式为:

我们之前研究的数据都是比较对称的数据,但是上图就给出了不对称的数据集,第一组用绿点表示,第二组用白点表示。通常,负偏度值表示左侧有一个占主导地位的尾巴,可以在第一个集合中看到。正偏度值对应于右侧较长或的尾巴,可以在第二组中看到。如果偏度接近0(例如,介于-0.5和0.5之间),则该数据集被认为是非常对称的。

那么不依赖第三包,怎么计算偏度。可以先计算完数据集的大小n,样本均值mean和标准差std后用公式计算

>>> x = [8.0, 1, 2.5, 4, 28.0]
>>> n = len(x)
>>> mean_ = sum(x) / n
>>> var_ = sum((item - mean_)**2 for item in x) / (n - 1)
>>> std_ = var_ ** 0.5
>>> skew_ = (sum((item - mean_)**3 for item in x)
...          * n / ((n - 1) * (n - 2) * std_**3))
>>> skew_
1.9470432273905929

可以看出偏度为正,因此x尾巴在右侧。

也可以用第三方包计算

>>> y, y_with_nan = np.array(x), np.array(x_with_nan)
>>> scipy.stats.skew(y, bias=False)
1.9470432273905927
>>> scipy.stats.skew(y_with_nan, bias=False)
nan
>>> z, z_with_nan = pd.Series(x), pd.Series(x_with_nan)
>>> z.skew()
1.9470432273905924
>>> z_with_nan.skew()
1.9470432273905924

百分位数(Percentiles)

如果将一组数据从小到大排序,并计算相应的累计百分位,则某一百分位所对应数据的值就称为这一百分位的百分位数。可表示为:一组n个观测值按数值大小排列。如,处于p%位置的值称第p百分位数。每个数据集都有三个四分位数,这是将数据集分为四个部分的百分位数:

  • 第一四分位数 (Q1),又称“较小四分位数”,等于该样本中所有数值由小到大排列后第25%的数字。

  • 第二四分位数 (Q2),又称“中位数”,等于该样本中所有数值由小到大排列后第50%的数字。

  • 第三四分位数 (Q3),又称“较大四分位数”,等于该样本中所有数值由小到大排列后第75%的数字。

第三四分位数与第一四分位数的差距又称四分位距(InterQuartile Range,IQR)。

那么在python里面怎么计算分位数呢。可以使用statistics.quantiles()

>>> x = [-5.0, -1.1, 0.1, 2.0, 8.0, 12.8, 21.0, 25.8, 41.0]
>>> statistics.quantiles(x, n=2)
[8.0]
>>> statistics.quantiles(x, n=4, method=\'inclusive\')
[0.1, 8.0, 21.0]

可以看到第一行中,8就是x的中位数,而第二个例子中,0.1和21是样本的25%和75%分位数。也可以使用第三方包numpy计算

>>> np.percentile(y, [25, 50, 75])
array([ 0.1,  8. , 21. ])
>>> np.median(y)
8.0
#跳过nan
>>> y_with_nan = np.insert(y, 2, np.nan)
>>> y_with_nan
array([-5. , -1.1,  nan,  0.1,  2. ,  8. , 12.8, 21. , 25.8, 41. ])
>>> np.nanpercentile(y_with_nan, [25, 50, 75])
array([ 0.1,  8. , 21. ])

pandas也可以使用

.quantile()

计算,需要提供分位数值作为参数。该值可以是0到1之间的数字或数字序列。

>>> z, z_with_nan = pd.Series(y), pd.Series(y_with_nan)
>>> z.quantile(0.05)
-3.44
>>> z.quantile(0.95)
34.919999999999995
>>> z.quantile([0.25, 0.5, 0.75])
0.25     0.1
0.50     8.0
0.75    21.0
dtype: float64
>>> z_with_nan.quantile([0.25, 0.5, 0.75])
0.25     0.1
0.50     8.0
0.75    21.0
dtype: float64

范围(Ranges)

数据的范围是数据集中最大和最小元素之间的差。可以通过函数np.ptp()获得:

>>> np.ptp(y)
27.0
>>> np.ptp(z)
27.0
>>> np.ptp(y_with_nan)
nan
>>> np.ptp(z_with_nan)
27.0

描述性统计摘要

在SciPy和Pandas提供过单个函数或方法调用快速获取描述性统计信息。

>>> result = scipy.stats.describe(y, ddof=1, bias=False)
>>> result
DescribeResult(nobs=9, minmax=(-5.0, 41.0), mean=11.622222222222222, variance=228.75194444444446, skewness=0.9249043136685094, kurtosis=0.14770623629658886)

describe()

 返回包含以下信息:

  • nobs:数据集中的观测值或元素数

  • minmax:数据的最大和最小值

  • mean:数据集的平均值

  • variance:数据集的方差

  • skewness:数据集的偏度

  • kurtosis:数据集的峰度

>>> result.nobs
9
>>> result.minmax[0]  # Min
-5.0
>>> result.minmax[1]  # Max
41.0
>>> result.mean
11.622222222222222
>>> result.variance
228.75194444444446
>>> result.skewness
0.9249043136685094
>>> result.kurtosis
0.14770623629658886

pandas也有类似的函数.describe():

>>> result = z.describe()
>>> result
count     9.000000 #数据集中的元素数
mean     11.622222 #数据集的平均值
std      15.124548 #数据集的标准差
min      -5.000000
25%       0.100000 #数据集的四分位数
50%       8.000000
75%      21.000000
max      41.000000
dtype: float64

相关性

相关行的统计学意义也不在过多说明,但是要注意,相关性只是能从数据上判断是否有关系,不能够说明因果关系!!!

度量相关性主要使用协方差和相关性系数:

那么我们先重新创建数据

>>> x = list(range(-10, 11))
>>> y = [0, 2, 2, 2, 2, 3, 3, 6, 7, 4, 7, 6, 6, 9, 4, 5, 5, 10, 11, 12, 14]
>>> x_, y_ = np.array(x), np.array(y)
>>> x__, y__ = pd.Series(x_), pd.Series(y_)

计算协方差

>>> n = len(x)
>>> mean_x, mean_y = sum(x) / n, sum(y) / n
>>> cov_xy = (sum((x[k] - mean_x) * (y[k] - mean_y) for k in range(n))
...           / (n - 1))
>>> cov_xy
19.95

numpyh和pandas都有可以返回协方差矩阵函数cov()

# numpy
>>> cov_matrix = np.cov(x_, y_)
>>> cov_matrix
array([[38.5       , 19.95      ],
      [19.95      , 13.91428571]])
# pandas
>>> cov_xy = x__.cov(y__)
>>> cov_xy
19.95
>>> cov_xy = y__.cov(x__)
>>> cov_xy
19.95

计算相关系数

我们这里说的均是pearson相关系数。Pearson相关系数(Pearson CorrelationCoefficient)是用来衡量两个数据集合是否在一条线上面,它用来衡量定距变量间的线性关系。计算公式为

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » 怎么样描述你的数据——用python做描述性分析