在Python中查找列表的中值

在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
712959 次浏览
sorted()函数对此非常有用。使用排序函数 要对列表排序,只需返回中间值(或两个中间值的平均值)

.如果列表包含偶数个元素,则返回值)
def median(lst):
sortedLst = sorted(lst)
lstLen = len(lst)
index = (lstLen - 1) // 2
   

if (lstLen % 2):
return sortedLst[index]
else:
return (sortedLst[index] + sortedLst[index + 1])/2.0

你可以使用list.sort来避免用sorted创建新的列表,并对列表进行排序。

另外,你不应该使用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]

(适用于< a href = " /问题/标签/ python 2。X " class="post-tag" title="show questions tagged 'python-2.x'" rel="tag">python-2.x . X):

def median(lst):
n = len(lst)
s = sorted(lst)
return (s[n//2-1]/2.0+s[n//2]/2.0, s[n//2])[n % 2] if n else None

>>> median([-5, -5, -3, -4, 0, -1])
-3.5

numpy.median():

>>> from numpy import median
>>> median([1, -4, -1, -1, 1, -3])
-1.0

对于,使用statistics.median:

>>> from statistics import median
>>> median([5, 2, 3, 8, 9, -2])
4.0

Python 3.4有statistics.median:

返回数值数据的中位数(中间值)。

当数据点数为奇数时,返回中间的数据点。 当数据点数为偶数时,通过取两个中间值的平均值来插值中位数:

>>> median([1, 3, 5])
3
>>> median([1, 3, 5, 7])
4.0

用法:

import statistics


items = [6, 1, 8, 2, 3]


statistics.median(items)
#>>> 3

它对类型也非常小心:

statistics.median(map(float, items))
#>>> 3.0


from decimal import Decimal
statistics.median(map(Decimal, items))
#>>> Decimal('3')

如果需要更快的平均情况运行时间,可以尝试quickselect算法。Quickselect具有平均(也是最好的)case性能O(n),尽管在糟糕的一天它可能会以O(n²)结束。

下面是一个随机选择枢轴的实现:

import random


def select_nth(n, items):
pivot = random.choice(items)


lesser = [item for item in items if item < pivot]
if len(lesser) > n:
return select_nth(n, lesser)
n -= len(lesser)


numequal = items.count(pivot)
if numequal > n:
return pivot
n -= numequal


greater = [item for item in items if item > pivot]
return select_nth(n, greater)

你可以简单地把它变成一个方法来寻找中位数:

def median(items):
if len(items) % 2:
return select_nth(len(items)//2, items)


else:
left  = select_nth((len(items)-1) // 2, items)
right = select_nth((len(items)+1) // 2, items)


return (left + right) / 2

这是非常未优化的,但即使是优化的版本也不太可能胜过Tim Sort (CPython的内置sort),因为它是非常快。我以前试过,但失败了。

我为一组数字定义了一个中值函数

def median(numbers):
return (sorted(numbers)[int(round((len(numbers) - 1) / 2.0))] + sorted(numbers)[int(round((len(numbers) - 1) // 2.0))]) / 2.0

这里有一个更干净的解决方案:

def median(lst):
quotient, remainder = divmod(len(lst), 2)
if remainder:
return sorted(lst)[quotient]
return sum(sorted(lst)[quotient - 1:quotient + 1]) / 2.

注:答案更改为在评论中加入建议。

中值函数

def median(midlist):
midlist.sort()
lens = len(midlist)
if lens % 2 != 0:
midl = (lens / 2)
res = midlist[midl]
else:
odd = (lens / 2) -1
ev = (lens / 2)
res = float(midlist[odd] + midlist[ev]) / float(2)
return res

我在“中位数的中位数”的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)
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

以下是我在Codecademy的练习中得出的结论:

def median(data):
new_list = sorted(data)
if len(new_list)%2 > 0:
return new_list[len(new_list)/2]
elif len(new_list)%2 == 0:
return (new_list[(len(new_list)/2)] + new_list[(len(new_list)/2)-1]) /2.0


print median([1,2,3,4,5,9])

下面是不使用median函数查找中位数的繁琐方法:

def median(*arg):
order(arg)
numArg = len(arg)
half = int(numArg/2)
if numArg/2 ==half:
print((arg[half-1]+arg[half])/2)
else:
print(int(arg[half]))


def order(tup):
ordered = [tup[i] for i in range(len(tup))]
test(ordered)
while(test(ordered)):
test(ordered)
print(ordered)




def test(ordered):
whileloop = 0
for i in range(len(ordered)-1):
print(i)
if (ordered[i]>ordered[i+1]):
print(str(ordered[i]) + ' is greater than ' + str(ordered[i+1]))
original = ordered[i+1]
ordered[i+1]=ordered[i]
ordered[i]=original
whileloop = 1 #run the loop again if you had to switch values
return whileloop

我在浮点值列表中遇到了一些问题。我最终使用了来自python3 statistics.median的代码片段,并且可以完美地使用浮点值而不导入。

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

当然,你可以使用内置函数,但如果你想创建自己的函数,你可以这样做。这里的技巧是使用~运算符将正数转换为负数。例如~2 -> -3和在Python中使用负in For list将从末尾开始计数。如果你有mid == 2,那么它会从开始取第三个元素,从结束取第三个元素。

def median(data):
data.sort()
mid = len(data) // 2
return (data[mid] + data[~mid]) / 2
def midme(list1):


list1.sort()
if len(list1)%2>0:
x = list1[int((len(list1)/2))]
else:
x = ((list1[int((len(list1)/2))-1])+(list1[int(((len(list1)/2)))]))/2
return x




midme([4,5,1,7,2])
def median(array):
if len(array) < 1:
return(None)
if len(array) % 2 == 0:
median = (array[len(array)//2-1: len(array)//2+1])
return sum(median) / len(median)
else:
return(array[len(array)//2])
def median(x):
x = sorted(x)
listlength = len(x)
num = listlength//2
if listlength%2==0:
middlenum = (x[num]+x[num-1])/2
else:
middlenum = x[num]
return middlenum

这很简单;

def median(alist):
#to find median you will have to sort the list first
sList = sorted(alist)
first = 0
last = len(sList)-1
midpoint = (first + last)//2
return midpoint

你可以像这样使用返回值median = median(anyList)

import numpy as np
def get_median(xs):
mid = len(xs) // 2  # Take the mid of the list
if len(xs) % 2 == 1: # check if the len of list is odd
return sorted(xs)[mid] #if true then mid will be median after sorting
else:
#return 0.5 * sum(sorted(xs)[mid - 1:mid + 1])
return 0.5 * np.sum(sorted(xs)[mid - 1:mid + 1]) #if false take the avg of mid
print(get_median([7, 7, 3, 1, 4, 5]))
print(get_median([1,2,3, 4,5]))

函数值:

def median(d):
d=np.sort(d)
n2=int(len(d)/2)
r=n2%2
if (r==0):
med=d[n2]
else:
med=(d[n2] + d[n2+1]) / 2
return med

如果您需要关于列表分布的额外信息,百分位数方法可能会很有用。中位数对应于列表的第50个百分位数:

import numpy as np
a = np.array([1,2,3,4,5,6,7,8,9])
median_value = np.percentile(a, 50) # return 50th percentile
print median_value

更普遍的中位数(和百分位数)方法是:

def get_percentile(data, percentile):
# Get the number of observations
cnt=len(data)
# Sort the list
data=sorted(data)
# Determine the split point
i=(cnt-1)*percentile
# Find the `floor` of the split point
diff=i-int(i)
# Return the weighted average of the value above and below the split point
return data[int(i)]*(1-diff)+data[int(i)+1]*(diff)


# Data
data=[1,2,3,4,5]
# For the median
print(get_percentile(data=data, percentile=.50))
# > 3
print(get_percentile(data=data, percentile=.75))
# > 4


# Note the weighted average difference when an int is not returned by the percentile
print(get_percentile(data=data, percentile=.51))
# > 3.04


一个返回给定列表中值的简单函数:

def median(lst):
lst = sorted(lst)  # Sort the list first
if len(lst) % 2 == 0:  # Checking if the length is even
# Applying formula which is sum of middle two divided by 2
return (lst[len(lst) // 2] + lst[(len(lst) - 1) // 2]) / 2
else:
# If length is odd then get middle value
return lst[len(lst) // 2]

median函数的一些例子:

>>> median([9, 12, 20, 21, 34, 80])  # Even
20.5
>>> median([9, 12, 80, 21, 34])  # Odd
21

如果你想使用库,你可以简单地做:

>>> import statistics
>>> statistics.median([9, 12, 20, 21, 34, 80])  # Even
20.5
>>> statistics.median([9, 12, 80, 21, 34])  # Odd
21

只要两行就够了。

def get_median(arr):
'''
Calculate the median of a sequence.
:param arr: list
:return: int or float
'''
arr = sorted(arr)
return arr[len(arr)//2] if len(arr) % 2 else (arr[len(arr)//2] + arr[len(arr)//2-1])/2

实现它:

def median(numbers):
"""
Calculate median of a list numbers.
:param numbers: the numbers to be calculated.
:return: median value of numbers.


>>> median([1, 3, 3, 6, 7, 8, 9])
6
>>> median([1, 2, 3, 4, 5, 6, 8, 9])
4.5
>>> import statistics
>>> import random
>>> numbers = random.sample(range(-50, 50), k=100)
>>> statistics.median(numbers) == median(numbers)
True
"""
numbers = sorted(numbers)
mid_index = len(numbers) // 2
return (
(numbers[mid_index] + numbers[mid_index - 1]) / 2 if mid_index % 2 == 0
else numbers[mid_index]
)




if __name__ == "__main__":
from doctest import testmod


testmod()

source from

我所做的是:

def median(a):
a = sorted(a)
if len(a) / 2 != int:
return a[len(a) / 2]
else:
return (a[len(a) / 2] + a[(len(a) / 2) - 1]) / 2

解释:基本上,如果列表中项目的数量是奇数,则返回中间的数字,否则,如果你是偶数列表的一半,python会自动舍入较大的数字,因此我们知道在此之前的数字将会少一(因为我们对它进行了排序),我们可以将默认的较大数字和小于它的数字相加,并除以2来找到中位数。

简单地说,创建一个中值函数,参数为数字列表,并调用该函数。

def median(l):
l = sorted(l)
lent = len(l)
if (lent % 2) == 0:
m = int(lent / 2)
result = l[m]
else:
m = int(float(lent / 2) - 0.5)
result = l[m]
return result

试试这个

import math
def find_median(arr):
if len(arr)%2==1:
med=math.ceil(len(arr)/2)-1
return arr[med]
else:
return -1
print(find_median([1,2,3,4,5,6,7,8]))