Comment trouvez-vous la médiane d'une liste dans Python? La liste peut être de n'importe quelle taille et les nombres ne sont pas garantis dans un ordre particulier.
Si la liste contient un nombre pair d'éléments, la fonction doit renvoyer la moyenne des deux médians.
Voici quelques exemples (triés pour l'affichage):
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 3.4 a statistics.median
:
Renvoie la médiane (valeur moyenne) des données numériques.
Lorsque le nombre de points de données est impair, retourne le point de données intermédiaire . Lorsque le nombre de points de données est pair, la médiane est interpolée en prenant la moyenne des deux valeurs centrales:
>>> median([1, 3, 5]) 3 >>> median([1, 3, 5, 7]) 4.0
Usage:
import statistics
items = [6, 1, 8, 2, 3]
statistics.median(items)
#>>> 3
C'est assez prudent avec les types aussi:
statistics.median(map(float, items))
#>>> 3.0
from decimal import Decimal
statistics.median(map(Decimal, items))
#>>> Decimal('3')
Pour python-2.x :
Utilisez numpy.median()
pour créer une fonction sur une ligne:
>>> from numpy import median
>>> median([1, -4, -1, -1, 1, -3])
-1.0
Ou, pour écrire une fonction :
def median(lst):
n = len(lst)
if n < 1:
return None
if n % 2 == 1:
return sorted(lst)[n//2]
else:
return sum(sorted(lst)[n//2-1:n//2+1])/2.0
>>> median([-5, -5, -3, -4, 0, -1])
-3.5
Pour python-3.x , utilisez statistics.median
:
>>> from statistics import median
>>> median([5, 2, 3, 8, 9, -2])
4.0
La fonction triée () est très utile pour cela. Utilisez la fonction triéepour ordonner la liste, puis renvoyez simplement la valeur centrale (ou faites la moyenne des deux valeurs moyennes Si la liste contient un nombre pair d’éléments).
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
Voici une solution plus propre:
def median(lst):
quotient, remainder = divmod(len(lst), 2)
if remainder:
return sorted(lst)[quotient]
return sum(sorted(lst)[quotient - 1:quotient + 1]) / 2.
Remarque: La réponse a été modifiée pour intégrer la suggestion dans les commentaires.
Vous pouvez essayer l’algorithme quickselect si des temps d’exécution plus rapides sont nécessaires. Quickselect a des performances de cas moyennes (et meilleures) O(n)
, bien que O(n²)
puisse se terminer un mauvais jour.
Voici une implémentation avec un pivot choisi au hasard:
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)
Vous pouvez facilement transformer ceci en une méthode de recherche de médianes:
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
Ceci est très peu optimisé, mais il est peu probable que même une version optimisée surpasse Tim Sort (sort
intégré de CPython) car c'est vraiment rapide. J'ai déjà essayé et j'ai perdu.
Bien sûr, vous pouvez utiliser les fonctions intégrées, mais si vous voulez créer les vôtres, vous pouvez faire quelque chose comme ça. Le truc ici consiste à utiliser ~ opérateur qui renverse le nombre positif en négatif. Par exemple, ~ 2 -> -3 et utiliser Négatif dans une liste en Python comptera les éléments à la fin. Donc, si vous avez mid == 2, il faudra le troisième élément du début et le troisième élément de la fin.
def median(data):
data.sort()
mid = len(data) // 2
return (data[mid] + data[~mid]) / 2
Vous pouvez utiliser le list.sort
pour éviter de créer de nouvelles listes avec sorted
et trier les listes en place.
De plus, vous ne devriez pas utiliser list
comme nom de variable car elle ombrage le propre list de 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]
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
Voici ce que je suis venu avec cet exercice dans 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])
import numpy as np
def median(x):
if len(x)%2==0:
x = sorted(x)
num = round(len(x)/2)
num2 = num-1
middlenum = (x[num]+x[num2])/2
else:
x = sorted(x)
listlength = len(x)
num = round(listlength / 2)
middlenum = x[num]
return middlenum
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])
J'ai eu quelques problèmes avec les listes de valeurs flottantes. J'ai fini par utiliser un extrait de code de python3 statistics.median et fonctionne parfaitement avec des valeurs float sans importations. la source
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
Fonction médiane
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
J'ai posté ma solution sur Implémentation Python de l'algorithme "median of medians" , ce qui est un peu plus rapide que d'utiliser sort (). Ma solution utilise 15 nombres par colonne, pour une vitesse ~ 5N qui est plus rapide que la vitesse ~ 10N d'utilisation de 5 nombres par colonne. La vitesse optimale est de ~ 4N, mais je peux me tromper à ce sujet.
Par demande de Tom dans son commentaire, j'ai ajouté mon code ici, pour référence. Je crois que la partie critique pour la vitesse utilise 15 nombres par colonne au lieu de 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)
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(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])
J'ai défini une fonction médiane pour une liste de nombres comme
def median(numbers):
return (sorted(numbers)[int(round((len(numbers) - 1) / 2.0))] + sorted(numbers)[int(round((len(numbers) - 1) // 2.0))]) / 2.0
C'est très simple;
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
Et vous pouvez utiliser la valeur de retour comme celle-ci median = median(anyList)