python可以做统计分析么_Python 汇总和计数进行统计分析

Python 汇总和计数进行统计分析,基于函数sum()和len(),可以给出算术平均值的简单定义,如下所示:

def mean(items):

return sum(items) / len(items)

虽然这个定义很简洁,却不能用于可迭代对象,只能用于支持len()函数的集合,这一点通过添加类型标示很容易发现。定义mean(items: Iterable) -> float不成立,因为Iterable类型不支持len()函数。

诚然,对可迭代对象即使是求简单的平均值或者标准差都是很困难的。在Python中,我们要么实例化这些序列对象,要么转而使用一些更复杂的运算来完成求值。

正确的定义方法如下:

from collections import Sequence

def mean(items: Sequence) -> float:

return sum(items) / len(items)

定义正确的类型标示以确保sum()和len()能正常工作。

下面的定义用简洁的表达式定义了平均值和标准差。

import math

s0 = len(data) # sum(x ** 0 for x in data)

s1 = sum(data) # sum(x ** 1 for x in data)

s2 = sum(x ** 2 for x in data)

mean = s1 / s0

stdev = math.sqrt(s2 / s0 - (s1 / s0) ** 2)

s0、s1和s2是3种求和,实现过程都比较简单,结构也类似。通过它们可以很方便地算出平均值。计算标准差虽然稍复杂一些,但仍然可行。

更复杂的统计函数仍然具备这种良好的对称性,包括相关度和最小方差线性回归。

两个样本之间的相关度可以通过它们的标准值计算出来,如下所示:

def z(x, μ_x: float, σ_x: float) -> float:

return (x - μ_x) / σ_x

计算过程是对每个样本x减去平均值μ_x,再除以标准差σ_x,返回结果以σ为单位。大约2/3的情况下偏差在±1σ范围内,偏差越大,出现的概率越小,超过±3σ的概率则小于1/100。

如下所示使用该标量函数:

>>> d = [2, 4, 4, 4, 5, 5, 7, 9]

>>> list(z(x, mean(d), stdev(d)) for x in d)

[-1.5, -0.5, -0.5, -0.5, 0.0, 0.0, 1.0, 2.0]

这里首先对变量d中的值进行归一化,把计算结果实例化到一个列表中。使用生成器表达式,将标量函数z()应用于序列对象。

利用上面的函数,可以给出函数mean()和stdev()的实现方法。

def mean(samples: Sequence) -> float:

return s1(samples) / s0(samples)

def stdev(samples: Sequence) -> float:

N = s0(samples)

return sqrt((s2(samples) / N) - (s1(samples) / N) ** 2)

用类似的方法,如下改写前面3个求和函数:

def s0(samples: Sequence) -> float:

return sum(1 for x in samples) # or len(data)

def s1(samples: Sequence) -> float:

return sum(x for x in samples) # or sum(data)

def s2(samples: Sequence) -> float:

return sum(x * x for x in samples)

尽管简洁明了,但该实现仍无法应用于可迭代对象。计算平均值时,需要对可迭代对象做一次汇总和一次计数。计算标准差时,需要做两次汇总和一次计数,针对这类统计相关的处理,必须将序列对象实例化,才能多次使用数据。

计算两个样本集相关性的函数实现如下:

def corr(samples1: Sequence, samples2: Sequence) -> float:

m_1, s_1 = mean(samples1), stdev(samples1)

m_2, s_2 = mean(samples2), stdev(samples2)

z_1 = (z( x, m_1, s_1 ) for x in samples1)

z_2 = (z( x, m_2, s_2 ) for x in samples2)

r = (sum(zx1 * zx2 for zx1, zx2 in zip(z_1, z_2))

/ len(samples1))

return r

上面的相关性计算用到了样本集的基本统计特征值:平均值和标准差。基于这些特征值,我们定义了两个生成器函数,计算每个样本集的归一值。接着用zip()函数(见下个示例)把两个归一化序列中的元素组对,计算每对的乘积。这个乘积序列的平均值即表示两个样本集的相关度。

计算两个样本集之间的相关度如下所示:

>>> # Height (m)

>>> xi = [1.47, 1.50, 1.52, 1.55, 1.57, 1.60, 1.63, 1.65,

... 1.68, 1.70, 1.73, 1.75, 1.78, 1.80, 1.83,]

>>> # Mass (kg)

>>> yi = [52.21,53.12,54.48,55.84,57.20,58.57,59.93,61.29,

... 63.11, 64.47, 66.28, 68.10, 69.92, 72.19, 74.46,]

>>> round(corr( xi, yi ), 5)

0.99458

这里的两个数据点序列xi和yi的相关度超过了0.99,表明二者关系紧密。

以上代码示例很好地体现了函数式编程的优点。我们用几个函数构建出了一个简单易用的统计模块,且每个函数只是简单的表达式。作为反例,不妨假设把corr()函数写成一个长而复杂的表达式,函数内部有很多只用了一次的内部变量,用复制粘贴的方法把它们替换成各自代表的表达式。不难看出,虽然这里的corr()函数仅由6行Python代码组成,但仍属于函数式编程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值