@@ -611,7 +611,7 @@ def median_high(data):
611
611
return data [n // 2 ]
612
612
613
613
614
- def median_grouped (data , interval = 1 ):
614
+ def median_grouped (data , interval = 1.0 ):
615
615
"""Estimates the median for numeric data binned around the midpoints
616
616
of consecutive, fixed-width intervals.
617
617
@@ -650,35 +650,34 @@ def median_grouped(data, interval=1):
650
650
by exact multiples of *interval*. This is essential for getting a
651
651
correct result. The function does not check this precondition.
652
652
653
+ Inputs may be any numeric type that can be coerced to a float during
654
+ the interpolation step.
655
+
653
656
"""
654
657
data = sorted (data )
655
658
n = len (data )
656
- if n == 0 :
659
+ if not n :
657
660
raise StatisticsError ("no median for empty data" )
658
- elif n == 1 :
659
- return data [0 ]
660
661
661
662
# Find the value at the midpoint. Remember this corresponds to the
662
663
# midpoint of the class interval.
663
664
x = data [n // 2 ]
664
665
665
- # Generate a clear error message for non-numeric data
666
- for obj in (x , interval ):
667
- if isinstance (obj , (str , bytes )):
668
- raise TypeError (f'expected a number but got { obj !r} ' )
669
-
670
666
# Using O(log n) bisection, find where all the x values occur in the data.
671
667
# All x will lie within data[i:j].
672
668
i = bisect_left (data , x )
673
669
j = bisect_right (data , x , lo = i )
674
670
671
+ # Coerce to floats, raising a TypeError if not possible
672
+ try :
673
+ interval = float (interval )
674
+ x = float (x )
675
+ except ValueError :
676
+ raise TypeError (f'Value cannot be converted to a float' )
677
+
675
678
# Interpolate the median using the formula found at:
676
679
# https://www.cuemath.com/data/median-of-grouped-data/
677
- try :
678
- L = x - interval / 2 # The lower limit of the median interval.
679
- except TypeError :
680
- # Coerce mixed types to float.
681
- L = float (x ) - float (interval ) / 2
680
+ L = x - interval / 2.0 # Lower limit of the median interval
682
681
cf = i # Cumulative frequency of the preceding interval
683
682
f = j - i # Number of elements in the median internal
684
683
return L + interval * (n / 2 - cf ) / f
0 commit comments