MCPcopy Index your code
hub / github.com/python/cpython / median_grouped

Function median_grouped

Lib/statistics.py:395–464  ·  view source on GitHub ↗

Estimates the median for numeric data binned around the midpoints of consecutive, fixed-width intervals. The *data* can be any iterable of numeric data with each value being exactly the midpoint of a bin. At least one value must be present. The *interval* is width of each bin.

(data, interval=1.0)

Source from the content-addressed store, hash-verified

393
394
395def median_grouped(data, interval=1.0):
396 """Estimates the median for numeric data binned around the midpoints
397 of consecutive, fixed-width intervals.
398
399 The *data* can be any iterable of numeric data with each value being
400 exactly the midpoint of a bin. At least one value must be present.
401
402 The *interval* is width of each bin.
403
404 For example, demographic information may have been summarized into
405 consecutive ten-year age groups with each group being represented
406 by the 5-year midpoints of the intervals:
407
408 >>> demographics = Counter({
409 ... 25: 172, # 20 to 30 years old
410 ... 35: 484, # 30 to 40 years old
411 ... 45: 387, # 40 to 50 years old
412 ... 55: 22, # 50 to 60 years old
413 ... 65: 6, # 60 to 70 years old
414 ... })
415
416 The 50th percentile (median) is the 536th person out of the 1071
417 member cohort. That person is in the 30 to 40 year old age group.
418
419 The regular median() function would assume that everyone in the
420 tricenarian age group was exactly 35 years old. A more tenable
421 assumption is that the 484 members of that age group are evenly
422 distributed between 30 and 40. For that, we use median_grouped().
423
424 >>> data = list(demographics.elements())
425 >>> median(data)
426 35
427 >>> round(median_grouped(data, interval=10), 1)
428 37.5
429
430 The caller is responsible for making sure the data points are separated
431 by exact multiples of *interval*. This is essential for getting a
432 correct result. The function does not check this precondition.
433
434 Inputs may be any numeric type that can be coerced to a float during
435 the interpolation step.
436
437 """
438 data = sorted(data)
439 n = len(data)
440 if not n:
441 raise StatisticsError("no median for empty data")
442
443 # Find the value at the midpoint. Remember this corresponds to the
444 # midpoint of the class interval.
445 x = data[n // 2]
446
447 # Using O(log n) bisection, find where all the x values occur in the data.
448 # All x will lie within data[i:j].
449 i = bisect_left(data, x)
450 j = bisect_right(data, x, lo=i)
451
452 # Coerce to floats, raising a TypeError if not possible

Callers

nothing calls this directly

Calls 3

bisect_leftFunction · 0.90
bisect_rightFunction · 0.90
StatisticsErrorClass · 0.85

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…