Python计算中位数和众数

一些代码:

def median(numbers):
'''Return the median of the list of numbers.'''
# Sort the list of numbers and take the middle element.
n = len(numbers)
copy = numbers[:] # So that "numbers" keeps its original order
copy.sort()
if n & 1: # There is an odd number of elements
return copy[n / 2]
else:
return (copy[n / 2 - 1] + copy[n / 2]) / 2

def mode(numbers):
'''Return the mode of the list of numbers.'''
#Find the value that occurs the most frequently in a data set
freq={}
for i in range(len(numbers)):
try:
freq[numbers[i]] += 1
except KeyError:
freq[numbers[i]] = 1
max = 0
mode = None
for k, v in freq.iteritems():
if v > max:
max = v
mode = k
return mode

同样的事用python stats module也可以做,对应的函数就是stats.median()和stats.mode(),但是我用stats.median()结果很奇怪,输入是一堆整数的list,结果median是小数。。希望高手告诉我这是为啥。。stats.mode返回一个list,第一个元素是众数的频度,第二个元素是所有众数的list(因为未必唯一),而上面的代码仅返回其中一个众数,当然简单改进一下就和stats.mode()完全一样啦

Reference:
http://mail.python.org/pipermail/python-list/2004-December/294990.html

以下文章也许和本文有点关系:

4条留言 跳到评论框

  1. Song Li
    发表于May 15, 2008 12:49 PM | 永久链接

    看看原始的stats的code,他先做了一个histogram然后用一个median公式算得median.我估计是因为在公式里他加了float,所以有了floating point error. 我做了一个小的simulation,R里面就没有这个问题,因为R是通过sorting来找到median.估计是histogram比sorting快,所以stats采用了histogram的方法。

    [回复这条留言]

  2. azalea
    发表于May 15, 2008 1:52 PM | 永久链接

    以前看到求median的算法是o(nlogn),和quick sort的平均复杂度一样,没必要通过histogram来算啊。
    这么说来这个是stats module的问题?我还以为是我自己的问题-,-
    我去stats里面没有找到median()函数,汗。。

    [回复这条留言]

  3. Song Li
    发表于May 15, 2008 2:03 PM | 永久链接

    应该说是python浮点计算的问题,我刚在newsmth.net上看到一群人讨论python的浮点计算,有人所python的浮点计算是所有语言里(Java,C++,fortran),里最差的,被人狂拍,结果还都没拍到点子上。python一来就不是作浮点计算而设计的,还是用R方便。scipy存在了这么久,也没看到特别多的应用。

    [回复这条留言]

  4. azalea
    发表于May 15, 2008 2:32 PM | 永久链接

    是啊,sigh..
    好像scipy里连lowess都没有

    [回复这条留言]

发表新留言

*
*