Rank order a dataset. The lowest value has rank 1. Ties are averaged so that equal values receive the same rank: >>> data = [31, 56, 31, 25, 75, 18] >>> _rank(data) [3.5, 5.0, 3.5, 2.0, 6.0, 1.0] The operation is idempotent: >>> _rank([3.5, 5.0, 3.5, 2.0,
(data, /, *, key=None, reverse=False, ties='average', start=1)
| 1649 | |
| 1650 | |
| 1651 | def _rank(data, /, *, key=None, reverse=False, ties='average', start=1) -> list[float]: |
| 1652 | """Rank order a dataset. The lowest value has rank 1. |
| 1653 | |
| 1654 | Ties are averaged so that equal values receive the same rank: |
| 1655 | |
| 1656 | >>> data = [31, 56, 31, 25, 75, 18] |
| 1657 | >>> _rank(data) |
| 1658 | [3.5, 5.0, 3.5, 2.0, 6.0, 1.0] |
| 1659 | |
| 1660 | The operation is idempotent: |
| 1661 | |
| 1662 | >>> _rank([3.5, 5.0, 3.5, 2.0, 6.0, 1.0]) |
| 1663 | [3.5, 5.0, 3.5, 2.0, 6.0, 1.0] |
| 1664 | |
| 1665 | It is possible to rank the data in reverse order so that the |
| 1666 | highest value has rank 1. Also, a key-function can extract |
| 1667 | the field to be ranked: |
| 1668 | |
| 1669 | >>> goals = [('eagles', 45), ('bears', 48), ('lions', 44)] |
| 1670 | >>> _rank(goals, key=itemgetter(1), reverse=True) |
| 1671 | [2.0, 1.0, 3.0] |
| 1672 | |
| 1673 | Ranks are conventionally numbered starting from one; however, |
| 1674 | setting *start* to zero allows the ranks to be used as array indices: |
| 1675 | |
| 1676 | >>> prize = ['Gold', 'Silver', 'Bronze', 'Certificate'] |
| 1677 | >>> scores = [8.1, 7.3, 9.4, 8.3] |
| 1678 | >>> [prize[int(i)] for i in _rank(scores, start=0, reverse=True)] |
| 1679 | ['Bronze', 'Certificate', 'Gold', 'Silver'] |
| 1680 | |
| 1681 | """ |
| 1682 | # If this function becomes public at some point, more thought |
| 1683 | # needs to be given to the signature. A list of ints is |
| 1684 | # plausible when ties is "min" or "max". When ties is "average", |
| 1685 | # either list[float] or list[Fraction] is plausible. |
| 1686 | |
| 1687 | # Default handling of ties matches scipy.stats.mstats.spearmanr. |
| 1688 | if ties != 'average': |
| 1689 | raise ValueError(f'Unknown tie resolution method: {ties!r}') |
| 1690 | if key is not None: |
| 1691 | data = map(key, data) |
| 1692 | val_pos = sorted(zip(data, count()), reverse=reverse) |
| 1693 | i = start - 1 |
| 1694 | result = [0] * len(val_pos) |
| 1695 | for _, g in groupby(val_pos, key=itemgetter(0)): |
| 1696 | group = list(g) |
| 1697 | size = len(group) |
| 1698 | rank = i + (size + 1) / 2 |
| 1699 | for value, orig_pos in group: |
| 1700 | result[orig_pos] = rank |
| 1701 | i += size |
| 1702 | return result |
| 1703 | |
| 1704 | |
| 1705 | def _integer_sqrt_of_frac_rto(n: int, m: int) -> int: |
no test coverage detected
searching dependent graphs…