References
Using those references:
- rolling median implementations benchmark
- FAST RUNNING MEDIAN USING AN INDEXABLE SKIPLIST
- Calculate the median of a billion numbers
- Find running median from a stream of integers
Code
A code was written to calculate the Median with the SortedContainers library:
from itertools import islice
from sortedcontainers import SortedList
import random
import time
start_time = time.time()
class Median(object):
def __init__(self, iterable):
self._iterable = islice(iterable, None)
self._sortedlist = SortedList(self._iterable)
def __iter__(self):
self_sortedlist = self._sortedlist
# print(self_sortedlist)
length = len(self_sortedlist)
half = length // 2
if length % 2 == 0:
yield (self_sortedlist[half] + self_sortedlist[half - 1]) // 2
elif length % 2 == 1:
yield self_sortedlist[half]
def main():
m, n = 1000, 1500000
data = [random.randrange(m) for i in range(n)]
# print("Random Data: ", data)
result = list(Median(data))
print("Result: ", result)
if __name__ == "__main__":
main()
print("--- %s seconds ---" % (time.time() - start_time))
Explanation
Random Number Generator
The following code generates data within the Range m
and quantity n
.
m, n = 1000, 15000000
data = [random.randrange(m) for i in range(n)]
Median
The Median class sorts the list of numbers and if n
is odd, returns the middle item with yield self_sortedlist[half]
. Or if n
is even, returns the mean of two middle itens of the list with yield (self_sortedlist[half] + self_sortedlist[half - 1]) // 2
Question
How do I improve the code performance? Because for a large list (100 milion), it takes --- 186.7168517112732 seconds---
on my computer.
O(n log n)
. You may want to look into Medians of Medians (scroll down for a python implementation) which has linear time complexity. \$\endgroup\$