Encontrando la mediana de la lista en Python

¿Cómo encuentras la mediana de una lista en Python? La lista puede ser de cualquier tamaño y no se garantiza que los números estén en ningún orden en particular.

Si la lista contiene un número par de elementos, la función debe devolver el promedio de los dos medios.

Aquí hay algunos ejemplos (ordenados para propósitos de visualización):

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 tiene statistics.median :

    Devuelve la mediana (valor medio) de los datos numéricos.

    Cuando el número de puntos de datos es impar, devuelva el punto de datos medio. Cuando el número de puntos de datos es par, la mediana se interpola tomando el promedio de los dos valores medios:

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

    Uso:

     import statistics items = [6, 1, 8, 2, 3] statistics.median(items) #>>> 3 

    Es bastante cuidadoso con los tipos, también:

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

    Para python-2.x :

    Use numpy.median() para hacer una función de una línea:

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

    O, para escribir una función :

     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 

    Para python-3.x , usa statistics.median :

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

    La función ordenada () es muy útil para esto. Utilice la función ordenada para ordenar la lista, luego simplemente devuelva el valor medio (o promedie los dos valores medios si la lista contiene una cantidad uniforme de elementos).

     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 

    Aquí hay una solución más limpia:

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

    Nota: Respuesta modificada para incorporar sugerencias en comentarios.

    Puede probar el algoritmo de selección rápida si se necesitan tiempos de ejecución promedio de caso más rápidos. Quickselect tiene un rendimiento de caso promedio (y mejor) O(n) , aunque puede terminar con O(n²) en un día malo.

    Aquí hay una implementación con un pivote elegido al azar:

     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) 

    Trivialmente puede convertir esto en un método para encontrar medianas:

     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 

    Esto no está muy optimizado, pero no es probable que incluso una versión optimizada supere a Tim Sort (clasificación integrada de CPython) porque eso es realmente rápido . Lo he intentado antes y lo he perdido.

    Por supuesto, puedes usar funciones integradas, pero si quieres crear las tuyas, puedes hacer algo como esto. El truco aquí es usar el operador ~ que cambia el número positivo a negativo. Por ejemplo, ~ 2 -> -3 y el uso negativo en la lista en Python contará los elementos del final. Entonces, si tiene una media de == 2, tomará el tercer elemento del principio y el tercer elemento del final.

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

    Puede usar list.sort para evitar crear nuevas listas sorted y ordenar las listas en su lugar.

    Además, no debe usar la list como nombre de variable, ya que ésta sombrea la propia lista 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 

    Aquí lo que se me ocurrió durante este ejercicio en 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 

    función mediana

     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 

    Publiqué mi solución en la implementación de Python del algoritmo “mediana de medianas” , que es un poco más rápido que usar sort (). Mi solución usa 15 números por columna, para una velocidad ~ 5N que es más rápida que la velocidad ~ 10N de usar 5 números por columna. La velocidad óptima es ~ 4N, pero podría estar equivocado al respecto.

    Por la solicitud de Tom en su comentario, agregué mi código aquí, para referencia. Creo que la parte crítica para la velocidad es usar 15 números por columna, en lugar 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) 

    Tuve algunos problemas con las listas de valores flotantes. Terminé usando un fragmento de código de python3 statistics.median y funciona perfectamente con valores flotantes sin importaciones. fuente

     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 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]) 

    Definí una función mediana para una lista de números como

     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(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]) 

    Es muy 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 

    Y puede usar el valor de retorno como esta median = median(anyList)

    Aquí está la forma tediosa de encontrar la mediana sin usar la función de la 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