【问题标题】:Finding the average of a list查找列表的平均值
【发布时间】:2012-02-20 20:03:29
【问题描述】:

我必须在 Python 中找到一个列表的平均值。这是我目前的代码

from functools import reduce

l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
print(reduce(lambda x, y: x + y, l))

我知道了,所以它将列表中的值相加,但我不知道如何将其分成它们?

【问题讨论】:

  • numpy.mean 如果你能负担得起安装 numpy
  • sum(L) / float(len(L))。处理调用者代码中的空列表,例如if not L: ...
  • @mitch:这不是您是否负担得起安装 numpy 的问题。 numpy 本身就是一个完整的词。这是你是否真的需要numpy。安装 numpy,一个 16mb 的 C 扩展,用于平均计算是非常不切实际的,对于不将它用于其他事情的人来说。
  • 如果使用 python 3,我们可以通过“从统计导入均值”或者在 python 2.7 或更低版本上使用 statistic 模块来完成这件事,而不是仅安装整个 numpy 包 avg/mean,统计模块可以从src:hg.python.org/cpython/file/default/Lib/statistics.pydoc:docs.python.org/dev/library/statistics.html下载直接使用。

标签: python list lambda average reduce


【解决方案1】:

在 Python 3.8+ 上,使用浮点数,您可以使用 statistics.fmean,因为使用浮点数更快。

在 Python 3.4+ 上,您可以使用 statistics.mean:

l = [15, 18, 2, 36, 12, 78, 5, 6, 9]

import statistics
statistics.mean(l)  # = 20.11111111111111

在旧版本的 Python 上,您可以:

sum(l) / len(l)

在 Python 2 上,您需要将 len 转换为浮点数才能得到浮点除法

sum(l) / float(len(l))

没有必要使用functools.reduce,因为它要慢得多。

【讨论】:

  • 太完美了!抱歉这个愚蠢的问题,但我真的到处寻找!非常感谢!
  • 正如我所说,我是新手,我想我必须用循环或其他东西来计算其中的数字数量,我没有意识到我可以只需使用长度。这是我用 python 做的第一件事..
  • @CarlaDessi:你用的是什么教程?这在我看过的所有教程中都有详尽的介绍。显然,您发现了一个没有很好地涵盖这一点的教程。你用什么教程来学习 Python?
  • 如果总和是一个不适合 int/float 的大数怎么办?
  • @FooBarUser 那么你应该计算 k = 1.0/len(l),然后减少:reduce(lambda x, y: x + y * k, l)
【解决方案2】:
l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
sum(l) / len(l)

【讨论】:

  • 作为一个 C++ 程序员,这简直是天方夜谭,float 一点也不丑!
  • 如果你想减少小数点后的一些数字。这可能会派上用场:float('%.2f' % float(sum(l) / len(l)))
  • @Steinfeld 我不认为转换为字符串是最好的方法。您可以使用round(result, 2) 以更简洁的方式实现相同目的。
【解决方案3】:

你可以使用numpy.mean:

l = [15, 18, 2, 36, 12, 78, 5, 6, 9]

import numpy as np
print(np.mean(l))

【讨论】:

  • 这很奇怪。我本以为这会更有效率,但它似乎比简单的 sum(l)/len(l) 在随机的浮动列表上花费 8 倍
  • 哦,但是np.array(l).mean() 的速度要快得多
  • @L.AmberO'Hearn,我刚刚计时了,np.mean(l)np.array(l).mean 的速度差不多,sum(l)/len(l) 的速度大约是两倍。我使用了l = list(np.random.rand(1000)),当然如果lnumpy.array,那么numpy 方法都会变得更快。
  • 好吧,除非这是安装 numpy 的唯一原因。安装一个 16mb 的 C 包以进行平均计算在这种规模上看起来很奇怪。
  • 另外最好使用np.nanmean(l) 以避免出现 NANzero 分割问题
【解决方案4】:

statistics 模块已成为 added to python 3.4。它有一个计算平均值的函数,称为mean。您提供的列表示例如下:

from statistics import mean
l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
mean(l)

【讨论】:

  • 这是最优雅的答案,因为它使用了一个标准库模块,该模块从 python 3.4 开始可用。
  • 而且数值更稳定
  • 如果你不小心传入了一个空列表statistics.StatisticsError: mean requires at least one data point,而不是sum(x) / len(x)解决方案的更神秘的ZeroDivisionError: division by zero,它会产生一个更好的错误。
【解决方案5】:

当 Python 有一个完美的 sum() 函数时,为什么还要使用 reduce() 呢?

print sum(l) / float(len(l))

float() 在 Python 2 中是强制 Python 进行浮点除法所必需的。)

【讨论】:

  • 对于我们这些对@987654321这个词不熟悉的人@
  • float() 在 Python 3 上不是必需的。
【解决方案6】:

如果您使用的是 python >= 3.4,则有一个统计库

https://docs.python.org/3/library/statistics.html

你可以像这样使用它的平均方法。假设您有一个数字列表,您希望找到其中的平均值:-

list = [11, 13, 12, 15, 17]
import statistics as s
s.mean(list)

它还有其他方法,例如标准差、方差、众数、调和平均数、中位数等,它们太有用了。

【讨论】:

    【解决方案7】:

    您可以将 0.0 添加到总和中,而不是强制转换为浮点数:

    def avg(l):
        return sum(l, 0.0) / len(l)
    

    【讨论】:

      【解决方案8】:

      编辑:

      我添加了另外两种获取列表平均值的方法(仅适用于 Python 3.8+)。这是我做的比较:

      # test mean caculation
      
      import timeit
      import statistics
      import numpy as np
      from functools import reduce
      import pandas as pd
      import math
      
      LIST_RANGE = 10000000000
      NUMBERS_OF_TIMES_TO_TEST = 10000
      
      l = list(range(10))
      
      def mean1():
          return statistics.mean(l)
      
      
      def mean2():
          return sum(l) / len(l)
      
      
      def mean3():
          return np.mean(l)
      
      
      def mean4():
          return np.array(l).mean()
      
      
      def mean5():
          return reduce(lambda x, y: x + y / float(len(l)), l, 0)
      
      def mean6():
          return pd.Series(l).mean()
      
      
      def mean7():
          return statistics.fmean(l)
      
      
      def mean8():
          return math.fsum(l) / len(l)
      
      
      for func in [mean1, mean2, mean3, mean4, mean5, mean6, mean7, mean8 ]:
          print(f"{func.__name__} took: ",  timeit.timeit(stmt=func, number=NUMBERS_OF_TIMES_TO_TEST))
      

      这些是我得到的结果:

      mean1 took:  0.09751558300000002
      mean2 took:  0.005496791999999973
      mean3 took:  0.07754683299999998
      mean4 took:  0.055743208000000044
      mean5 took:  0.018134082999999968
      mean6 took:  0.6663848750000001
      mean7 took:  0.004305374999999945
      mean8 took:  0.003203333000000086
      

      有趣!看起来math.fsum(l) / len(l) 是最快的方式,然后是statistics.fmean(l),然后才是sum(l) / len(l)。不错!

      感谢@Asclepius 向我展示了这两种其他方式!


      旧答案:

      在效率和速度方面,这些是我测试其他答案得到的结果:

      # test mean caculation
      
      import timeit
      import statistics
      import numpy as np
      from functools import reduce
      import pandas as pd
      
      LIST_RANGE = 10000000000
      NUMBERS_OF_TIMES_TO_TEST = 10000
      
      l = list(range(10))
      
      def mean1():
          return statistics.mean(l)
      
      
      def mean2():
          return sum(l) / len(l)
      
      
      def mean3():
          return np.mean(l)
      
      
      def mean4():
          return np.array(l).mean()
      
      
      def mean5():
          return reduce(lambda x, y: x + y / float(len(l)), l, 0)
      
      def mean6():
          return pd.Series(l).mean()
      
      
      
      for func in [mean1, mean2, mean3, mean4, mean5, mean6]:
          print(f"{func.__name__} took: ",  timeit.timeit(stmt=func, number=NUMBERS_OF_TIMES_TO_TEST))
      

      结果:

      mean1 took:  0.17030245899968577
      mean2 took:  0.002183011999932205
      mean3 took:  0.09744236000005913
      mean4 took:  0.07070840100004716
      mean5 took:  0.022754742999950395
      mean6 took:  1.6689282460001778
      

      很明显,获胜者是: sum(l) / len(l)

      【讨论】:

      • 我用长度为 100000000 的列表尝试了这些计时:mean2
      • 顺便说一句,如果我先将 l 转换为 np.arraynp.mean 需要 ~.16 秒,因此比 sum(l)/len(l) 快大约 6 倍。结论:如果您要进行大量计算,最好在 numpy 中进行所有操作。
      • @drevicko 见mean4,这就是我在那里所做的......我猜它已经是一个 np.array 那么使用np.mean 是有意义的,但如果你有一个列出然后你应该使用sum(l) / len(l)
      • 没错!这也取决于你以后要用它做什么。我的工作是我通常会进行一系列计算,因此在开始时转换为 numpy 并利用 numpy 的快速底层库是有意义的。
      • @AlonGouldman 太好了。我强烈建议以 1/1000 秒(作为整数)显示每个速度,否则数字很难阅读。例如,170、2、97 等。这应该使它更容易阅读。请让我知道这是否完成,我会检查。
      【解决方案9】:

      sum(l) / float(len(l)) 是正确答案,但为了完整起见,您可以使用单个 reduce 计算平均值:

      >>> reduce(lambda x, y: x + y / float(len(l)), l, 0)
      20.111111111111114
      

      请注意,这可能会导致轻微的舍入误差:

      >>> sum(l) / float(len(l))
      20.111111111111111
      

      【讨论】:

      • 我知道这只是为了好玩,但为空列表返回 0 可能不是最好的选择
      • @JohanLundberg - 您可以将 0 替换为 False 作为reduce() 的最后一个参数,这将为您提供空列表的 False,否则为之前的平均值。
      • @AndrewClark 为什么要强制floaton len
      【解决方案10】:

      我尝试使用上述选项,但没有奏效。 试试这个:

      from statistics import mean
      
      n = [11, 13, 15, 17, 19]
      
      print(n)
      print(mean(n))
      

      在 python 3.5 上工作

      【讨论】:

        【解决方案11】:

        或者使用pandasSeries.mean方法:

        pd.Series(sequence).mean()
        

        演示:

        >>> import pandas as pd
        >>> l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
        >>> pd.Series(l).mean()
        20.11111111111111
        >>> 
        

        来自文档:

        Series.mean(axis=None, skipna=None, level=None, numeric_only=None, **kwargs)

        以下是相关文档:

        https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.mean.html

        以及整个文档:

        https://pandas.pydata.org/pandas-docs/stable/10min.html

        【讨论】:

        • 这不是pandas的问题,所以为了求均值这样的简单操作导入这么重的库似乎有些过分了。
        【解决方案12】:

        在 Udacity 的问题中,我有一个类似的问题要解决。而不是我编码的内置函数:

        def list_mean(n):
        
            summing = float(sum(n))
            count = float(len(n))
            if n == []:
                return False
            return float(summing/count)
        

        比平时长得多,但对于初学者来说,这很有挑战性。

        【讨论】:

        • 好。其他所有答案都没有注意到空列表的危险!
        • 返回False(相当于整数0)几乎是处理此错误的最糟糕的方法。最好抓住ZeroDivisionError 并提出更好的东西(也许ValueError)。
        • @kindall ValueErrorZeroDivisionError 好多少?后者更具体,而且似乎没有必要为了重新抛出一个不同的错误而捕获算术错误。
        • 因为ZeroDivisionError 仅在您知道如何进行计算时才有用(即涉及除以列表长度)。如果您不知道,它不会告诉您传入的值有什么问题。而您的新异常可以包含更具体的信息。
        【解决方案13】:

        作为初学者,我只是编写了这个代码:

        L = [15, 18, 2, 36, 12, 78, 5, 6, 9]
        
        total = 0
        
        def average(numbers):
            total = sum(numbers)
            total = float(total)
            return total / len(numbers)
        
        print average(L)
        

        【讨论】:

        • Bravo:恕我直言,sum(l)/len(l) 是迄今为止最优雅的答案(无需在 Python 3 中进行类型转换)。
        • 不需要将值存储在变量中或使用全局变量。
        【解决方案14】:

        如果您想获得的不仅仅是平均值(也就是平均值),您可以查看 scipy stats:

        from scipy import stats
        l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
        print(stats.describe(l))
        
        # DescribeResult(nobs=9, minmax=(2, 78), mean=20.11111111111111, 
        # variance=572.3611111111111, skewness=1.7791785448425341, 
        # kurtosis=1.9422716419666397)
        

        【讨论】:

          【解决方案15】:

          为了使用reduce 获取运行平均值,您需要跟踪总数以及到目前为止看到的元素总数。由于这不是列表中的一个微不足道的元素,因此您还必须传递 reduce 一个额外的参数来折叠。

          >>> l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
          >>> running_average = reduce(lambda aggr, elem: (aggr[0] + elem, aggr[1]+1), l, (0.0,0))
          >>> running_average[0]
          (181.0, 9)
          >>> running_average[0]/running_average[1]
          20.111111111111111
          

          【讨论】:

          • 很有趣,但这不是他想要的。
          【解决方案16】:

          两者都可以在整数或至少 10 个十进制值上为您提供接近相似的值。但是,如果您真的在考虑长浮点值,则两者可能会有所不同。方法可能因您想要实现的目标而异。

          >>> l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
          >>> print reduce(lambda x, y: x + y, l) / len(l)
          20
          >>> sum(l)/len(l)
          20
          

          浮动值

          >>> print reduce(lambda x, y: x + y, l) / float(len(l))
          20.1111111111
          >>> print sum(l)/float(len(l))
          20.1111111111
          

          @Andrew Clark 的陈述是正确的。

          【讨论】:

            【解决方案17】:

            假设

            x = [
                [-5.01,-5.43,1.08,0.86,-2.67,4.94,-2.51,-2.25,5.56,1.03],
                [-8.12,-3.48,-5.52,-3.78,0.63,3.29,2.09,-2.13,2.86,-3.33],
                [-3.68,-3.54,1.66,-4.11,7.39,2.08,-2.59,-6.94,-2.26,4.33]
            ]
            

            您可以注意到x 的尺寸为 3*10,如果您需要在每一行中输入 mean,您可以输入此内容

            theMean = np.mean(x1,axis=1)
            

            别忘了import numpy as np

            【讨论】:

              【解决方案18】:
              l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
              
              l = map(float,l)
              print '%.2f' %(sum(l)/len(l))
              

              【讨论】:

              • 效率低下。它在添加之前将所有元素转换为浮点数。只转换长度会更快。
              【解决方案19】:

              在列表中查找平均值 通过使用以下 PYTHON 代码:

              l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
              print(sum(l)//len(l))
              

              试试这个很简单。

              【讨论】:

                【解决方案20】:
                print reduce(lambda x, y: x + y, l)/(len(l)*1.0)
                

                或喜欢之前发布的内容

                sum(l)/(len(l)*1.0)
                

                1.0 是为了确保你得到一个浮点除法

                【讨论】:

                  【解决方案21】:

                  结合上述几个答案,我想出了以下与 reduce 一起使用的方法,并且不假设您在 reduce 函数中有 L 可用:

                  from operator import truediv
                  
                  L = [15, 18, 2, 36, 12, 78, 5, 6, 9]
                  
                  def sum_and_count(x, y):
                      try:
                          return (x[0] + y, x[1] + 1)
                      except TypeError:
                          return (x + y, 2)
                  
                  truediv(*reduce(sum_and_count, L))
                  
                  # prints 
                  20.11111111111111
                  

                  【讨论】:

                    【解决方案22】:

                    我只想添加另一种方法

                    import itertools,operator
                    list(itertools.accumulate(l,operator.add)).pop(-1) / len(l)
                    

                    【讨论】:

                      【解决方案23】:
                      numbers = [0,1,2,3]
                      
                      numbers[0] = input("Please enter a number")
                      
                      numbers[1] = input("Please enter a second number")
                      
                      numbers[2] = input("Please enter a third number")
                      
                      numbers[3] = input("Please enter a fourth number")
                      
                      print (numbers)
                      
                      print ("Finding the Avarage")
                      
                      avarage = int(numbers[0]) + int(numbers[1]) + int(numbers[2]) + int(numbers [3]) / 4
                      
                      print (avarage)
                      

                      【讨论】:

                      • 如果用户将浮点数添加到您的数组中怎么办?结果将非常不精确。
                      猜你喜欢
                      • 2020-08-10
                      • 2018-07-12
                      • 2015-05-17
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2020-10-15
                      相关资源
                      最近更新 更多