Mediaanlijst vinden in Python

Hoe vind je de mediaan van een lijst in Python? De lijst kan van groot formaat zijn en de cijfers zijn niet gegarandeerd in een bepaalde volgorde.

Als de lijst een even aantal elementen bevat, moet de functie het gemiddelde van de middelste twee retourneren.

Hier zijn enkele voorbeelden (gesorteerd voor weergavedoeleinden):

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

1, Autoriteit 100%

Python 3.4 heeft statistics.median:

Retourneer de mediaan (middelste waarde) van numerieke gegevens.

Wanneer het aantal gegevenspunten oneven is, retourneert u het Midden-gegevenspunt.
Wanneer het aantal gegevenspunten zelfs is, wordt de mediaan geïnterpoleerd door het gemiddelde van de twee middelste waarden te nemen:

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

Gebruik:

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

Het is ook vrij voorzichtig met typen:

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

2, Autoriteit 70%

(Werkt met python-3 .x, gebruik statistics.median:

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

Antwoord 3, autoriteit 24%

De functie sorted()is hiervoor erg handig. Gebruik de gesorteerde functie
om de lijst te ordenen, retourneer dan gewoon de middelste waarde (of het gemiddelde van de twee middelste
waarden als de lijst een even aantal elementen bevat).

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

Antwoord 4, autoriteit 5%

Hier is een schonere oplossing:

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

Opmerking: Antwoord gewijzigd om suggestie op te nemen in opmerkingen.


Antwoord 5, autoriteit 5%

Natuurlijk kunt u ingebouwde functies gebruiken, maar als u uw eigen functies wilt maken, kunt u zoiets als dit doen. De truc hier is om de ~-operator te gebruiken die het positieve getal omdraait naar negatief. Bijvoorbeeld ~2 -> -3 en het gebruik van negatief in voor lijst in Python zal items vanaf het einde tellen. Dus als je mid == 2 hebt, dan is het derde element vanaf het begin en het derde item vanaf het einde nodig.

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

Antwoord 6, autoriteit 4%

Je kunt het quickselect-algoritme proberen als er snellere gemiddelde looptijden nodig zijn. Quickselect heeft gemiddelde (en beste) prestaties O(n), hoewel het op een slechte dag O(n²)kan eindigen.

Hier is een implementatie met een willekeurig gekozen draaipunt:

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)

Je kunt dit triviaal veranderen in een methode om medianen te vinden:

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

Dit is erg ongeoptimaliseerd, maar het is niet waarschijnlijk dat zelfs een geoptimaliseerde versie beter zal presteren dan Tim Sort (CPython’s ingebouwde sort) omdat dat echt snelis. Ik heb het eerder geprobeerd en ik heb verloren.


Antwoord 7, autoriteit 4%

U kunt de list.sortgebruiken om te voorkomen dat u nieuwe lijsten maakt met sorteden de lijsten op hun plaats sorteren.

U moet ook geen listgebruiken als variabelenaam, aangezien deze de schaduw van Python’s eigen lijst.

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]

Antwoord 8, autoriteit 3%

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

Antwoord 9, autoriteit 3%

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

Antwoord 10, autoriteit 2%

Ik heb mijn oplossing gepost op Python-implementatie van “median of medians” algoritme, dat iets sneller is dan het gebruik van sort(). Mijn oplossing gebruikt 15 getallen per kolom, voor een snelheid van ~5N die sneller is dan de snelheid ~10N van het gebruik van 5 getallen per kolom. De optimale snelheid is ~4N, maar ik kan het mis hebben.

Op verzoek van Tom in zijn opmerking heb ik mijn code hier ter referentie toegevoegd. Ik geloof dat het kritieke deel voor snelheid 15 getallen per kolom gebruikt, in plaats van 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)

Antwoord 11

Hier kwam ik op tijdens deze oefening in 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])

Antwoord 12

mediaanfunctie

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

Antwoord 13

Ik had wat problemen met lijsten met float-waarden. Ik heb uiteindelijk een codefragment gebruikt uit de python3 statistics.medianen werkt perfect met float-waarden zonder import. bron

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

Antwoord 14

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

Antwoord 15

In het geval dat u aanvullende informatie nodig heeft over de distributie van uw lijst, zal de percentielmethode waarschijnlijk nuttig zijn. En een mediaanwaarde komt overeen met het 50e percentiel van een lijst:

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 

Antwoord 16

Slechts twee regels zijn genoeg.

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

Antwoord 17

Een eenvoudige functie om de mediaan van de gegeven lijst te retourneren:

def median(lst):
    lst.sort()  # 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]

Enkele voorbeelden met de functie median:

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

Als u de bibliotheek wilt gebruiken, kunt u eenvoudig het volgende doen:

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

Antwoord 18

Ik heb een mediaanfunctie voor een lijst met getallen gedefinieerd als

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

Antwoord 19

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

Antwoord 20

Functiemediaan:

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] + data[m+1]) / 2
    return med

21

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

22

Een meer gegeneraliseerde aanpak voor mediaan (en percentielen) zou zijn:

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

23

doe jezelf.

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

bron van


Antwoord 24

Maak eenvoudig een mediaanfunctie met een argument als een lijst van het getal en roep de functie aan.

def median(l):
        l.sort()
        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 ('median is: {}'.format(result))

Hopelijk helpt het, bedankt!


25

Hier is de vervelende manier om mediaan te vinden zonder de mediante gebruiken:

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

26

Het is heel eenvoudig;

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

En u kunt de retourwaarde zoals deze gebruiken median = median(anyList)

Other episodes