在Python中如何找到列表的中值?列表可以是任意大小的,并且数字不保证是任何特定的顺序。
如果列表包含偶数个元素,则函数应返回中间两个元素的平均值。
以下是一些例子(为了便于展示,进行了排序):
median([1]) == 1
median([1, 1]) == 1
median([1, 1, 2, 4]) == 1.5
median([0, 2, 5, 6, 8, 9, 9]) == 6
median([0, 0, 0, 0, 4, 4, 6, 8]) == 2
在Python中如何找到列表的中值?列表可以是任意大小的,并且数字不保证是任何特定的顺序。
如果列表包含偶数个元素,则函数应返回中间两个元素的平均值。
以下是一些例子(为了便于展示,进行了排序):
median([1]) == 1
median([1, 1]) == 1
median([1, 1, 2, 4]) == 1.5
median([0, 2, 5, 6, 8, 9, 9]) == 6
median([0, 0, 0, 0, 4, 4, 6, 8]) == 2
当前回答
def median(array):
"""Calculate median of the given list.
"""
# TODO: use statistics.median in Python 3
array = sorted(array)
half, odd = divmod(len(array), 2)
if odd:
return array[half]
return (array[half - 1] + array[half]) / 2.0
其他回答
当然,你可以使用内置函数,但如果你想创建自己的函数,你可以这样做。这里的技巧是使用~运算符将正数转换为负数。例如~2 -> -3和在Python中使用负in For list将从末尾开始计数。如果你有mid == 2,那么它会从开始取第三个元素,从结束取第三个元素。
def median(data):
data.sort()
mid = len(data) // 2
return (data[mid] + data[~mid]) / 2
我在浮点值列表中遇到了一些问题。我最终使用了来自python3统计数据的代码片段。中位数和工作完美的浮动值没有导入。源
def calculateMedian(list):
data = sorted(list)
n = len(data)
if n == 0:
return None
if n % 2 == 1:
return data[n // 2]
else:
i = n // 2
return (data[i - 1] + data[i]) / 2
我为一组数字定义了一个中值函数
def median(numbers):
return (sorted(numbers)[int(round((len(numbers) - 1) / 2.0))] + sorted(numbers)[int(round((len(numbers) - 1) // 2.0))]) / 2.0
你可以使用这个列表。排序以避免创建已排序的新列表,并对列表进行排序。
此外,你不应该使用list作为变量名,因为它会掩盖python自己的列表。
def median(l):
half = len(l) // 2
l.sort()
if not len(l) % 2:
return (l[half - 1] + l[half]) / 2.0
return l[half]
我在“中位数的中位数”算法的Python实现中发布了我的解决方案,这比使用sort()稍微快一点。我的解决方案每列使用15个数字,速度~5N比每列使用5个数字的速度~10N快。最佳速度是~4N,但我可能是错的。
根据Tom在评论中的要求,我在这里添加了我的代码,以供参考。我认为速度的关键部分是每列使用15个数字,而不是5个。
#!/bin/pypy
#
# TH @stackoverflow, 2016-01-20, linear time "median of medians" algorithm
#
import sys, random
items_per_column = 15
def find_i_th_smallest( A, i ):
t = len(A)
if(t <= items_per_column):
# if A is a small list with less than items_per_column items, then:
#
# 1. do sort on A
# 2. find i-th smallest item of A
#
return sorted(A)[i]
else:
# 1. partition A into columns of k items each. k is odd, say 5.
# 2. find the median of every column
# 3. put all medians in a new list, say, B
#
B = [ find_i_th_smallest(k, (len(k) - 1)/2) for k in [A[j:(j + items_per_column)] for j in range(0,len(A),items_per_column)]]
# 4. find M, the median of B
#
M = find_i_th_smallest(B, (len(B) - 1)/2)
# 5. split A into 3 parts by M, { < M }, { == M }, and { > M }
# 6. find which above set has A's i-th smallest, recursively.
#
P1 = [ j for j in A if j < M ]
if(i < len(P1)):
return find_i_th_smallest( P1, i)
P3 = [ j for j in A if j > M ]
L3 = len(P3)
if(i < (t - L3)):
return M
return find_i_th_smallest( P3, i - (t - L3))
# How many numbers should be randomly generated for testing?
#
number_of_numbers = int(sys.argv[1])
# create a list of random positive integers
#
L = [ random.randint(0, number_of_numbers) for i in range(0, number_of_numbers) ]
# Show the original list
#
# print L
# This is for validation
#
# print sorted(L)[int((len(L) - 1)/2)]
# This is the result of the "median of medians" function.
# Its result should be the same as the above.
#
print find_i_th_smallest( L, (len(L) - 1) / 2)