【问题标题】:How do I calculate standard deviation in python without using numpy?如何在不使用 numpy 的情况下计算 python 中的标准偏差?
【发布时间】:2023-03-10 01:41:01
【问题描述】:

我试图在不使用numpy 或除math 之外的任何外部库的情况下计算python 中的标准偏差。我想在编写算法方面做得更好,并且在提高我的 Python 技能时,我只是将其作为一些“家庭作业”。我的目标是将this formula 翻译成python,但没有得到正确的结果。

我正在使用speeds = [86,87,88,86,87,85,86] 的一系列速度

当我跑步时:

std_dev = numpy.std(speeds)
print(std_dev)

我得到:0.903507902905。但我不想依赖 numpy。所以...

我的实现如下:

import math

speeds = [86,87,88,86,87,85,86]

def get_mean(array):
    sum = 0
    for i in array:
        sum = sum + i
    mean = sum/len(array)
    return mean

def get_std_dev(array):
    # get mu
    mean = get_mean(array)
    # (x[i] - mu)**2
    for i in array:
        array = (i - mean) ** 2
        return array
    sum_sqr_diff = 0
    # get sigma
    for i in array:
        sum_sqr_diff = sum_sqr_diff + i
        return sum_sqr_diff
    # get mean of squared differences
    variance = 1/len(array)
    mean_sqr_diff = (variance * sum_sqr_diff)
    
    std_dev = math.sqrt(mean_sqr_diff)
    return std_dev

std_dev = get_std_dev(speeds)
print(std_dev)

现在当我跑步时:

std_dev = get_std_dev(speeds)
print(std_dev)

我得到:[0] 但我期待 0.903507902905

我在这里错过了什么?

【问题讨论】:

  • math 不是外部库。
  • 您的意见是什么?我们如何重现这个答案?
  • 您正在定义速度并使用narrow_speed 调用它。这不会给你一个错误吗?
  • @ZainUlAbidin 所有代码都在问题正文中可用,但并非都在同一个块中。我已经编辑了展示我的实现的部分,以包含重现所需的所有内容。
  • 您的代码未返回[0]

标签: python algorithm statistics mean standard-deviation


【解决方案1】:
speeds = [86,87,88,86,87,85,86]

# Calculate the mean of the values in your list
mean_speeds = sum(speeds) / len(speeds)

# Calculate the variance of the values in your list
# This is 1/N * sum((x - mean(X))^2)
var_speeds = sum((x - mean_speeds) ** 2 for x in speeds) / len(speeds)

# Take the square root of variance to get standard deviation
sd_speeds = var_speeds ** 0.5

>>> sd_speeds
0.9035079029052513

【讨论】:

  • 当我运行它时,我得到1.0
  • 重启你的python内核。您所做的某件事与其中一个内置功能搞砸了。
  • 哦,没关系,你用的是python2.7,不是吗。添加from __future__ import division - 标准除法/ 在python 3.0 之前不是真正的除法,除非您从未来导入。
  • 是的,我使用的是 2.7。您的解决方案加上未来的部门导入现在对我有用。非常感谢您的帮助!
  • 很多 Linux 发行版都附带 py2.7 和 py3 - 你可能有 python3(但二进制文件是 python3 而不仅仅是 python)。您还可以考虑使用 anaconda 之类的东西来设置环境。 py2.7 已经过了生命周期。
【解决方案2】:

您的代码中的问题是数组的重用并在循环中间返回

def get_std_dev(array):
    # get mu
    mean = get_mean(array)       <-- this is 86.4
    # (x[i] - mu)**2
    for i in array:
        array = (i - mean) ** 2  <-- this is almost 0
        return array             <-- this is the value returned

现在让我们看看您正在使用的算法。请注意,有两个常用的标准偏差公式。关于哪一个是正确的存在各种争论。

sqrt(sum((x - mean)^2) / n)

sqrt(sum((x - mean)^2) / (n -1))

对于较大的 n 值,使用第一个公式,因为 -1 无关紧要。第一个公式可以简化为

sqrt(sum(x^2) /n - mean^2)

那么你将如何在 python 中做到这一点?

def std_dev1(array):
   n = len(array)
   mean = sum(array) / n
   sumsq = sum(v * v for v in array)
   return (sumsq / n - mean * mean) ** 0.5

【讨论】:

    【解决方案3】:

    代码中的一些问题,其中之一是for语句中的返回值。你可以试试这个

    def get_mean(array):
        return sum(array) / len(array)
    
    
    def get_std_dev(array):
        n = len(array)
        mean = get_mean(array)
        squares_arr = []
        for item in array:
            squares_arr.append((item - mean) ** 2)
        return math.sqrt(sum(squares_arr) / n)
    

    【讨论】:

      【解决方案4】:

      这个。你需要在 for 循环中去掉 return

      def get_std_dev(array):
          # get mu
          mean = get_mean(array)
          sum_sqr_diff = 0
          # get sigma
          for i in array:
              sum_sqr_diff = sum_sqr_diff + (i - mean)**2
          # get mean of squared differences
          variance = 1/len(array)
          mean_sqr_diff = (variance * sum_sqr_diff)
          
          std_dev = math.sqrt(mean_sqr_diff)
          return std_dev
      

      【讨论】:

        【解决方案5】:

        如果你不想使用numpy 也可以尝试使用python 中的statistics

        import statistics
        
        st_dev = statistics.pstdev(speeds)
        print(st_dev)
        

        或者如果您仍然愿意使用自定义解决方案,那么我建议您使用以下方式,使用列表理解而不是复杂的错误方法

        import math
        
        mean = sum(speeds) / len(speeds)
        var = sum((l-mean)**2 for l in speeds) / len(speeds)
        st_dev = math.sqrt(var)
        print(st_dev)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-11-27
          • 2022-01-23
          • 1970-01-01
          • 2014-07-24
          • 1970-01-01
          • 2013-02-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多