|
19 | 19 | ensure_float64, ensure_int64, ensure_object, ensure_platform_int,
|
20 | 20 | ensure_uint64, is_array_like, is_bool_dtype, is_categorical_dtype,
|
21 | 21 | is_complex_dtype, is_datetime64_any_dtype, is_datetime64tz_dtype,
|
22 |
| - is_datetimelike, is_extension_array_dtype, is_float_dtype, |
| 22 | + is_datetimelike, is_extension_array_dtype, is_float_dtype, is_integer, |
23 | 23 | is_integer_dtype, is_interval_dtype, is_list_like, is_numeric_dtype,
|
24 | 24 | is_object_dtype, is_period_dtype, is_scalar, is_signed_integer_dtype,
|
25 | 25 | is_sparse, is_timedelta64_dtype, is_unsigned_integer_dtype,
|
@@ -1724,6 +1724,89 @@ def func(arr, indexer, out, fill_value=np.nan):
|
1724 | 1724 | return out
|
1725 | 1725 |
|
1726 | 1726 |
|
| 1727 | +# ------------ # |
| 1728 | +# searchsorted # |
| 1729 | +# ------------ # |
| 1730 | + |
| 1731 | +def searchsorted(arr, value, side="left", sorter=None): |
| 1732 | + """ |
| 1733 | + Find indices where elements should be inserted to maintain order. |
| 1734 | +
|
| 1735 | + .. versionadded:: 0.25.0 |
| 1736 | +
|
| 1737 | + Find the indices into a sorted array `arr` (a) such that, if the |
| 1738 | + corresponding elements in `value` were inserted before the indices, |
| 1739 | + the order of `arr` would be preserved. |
| 1740 | +
|
| 1741 | + Assuming that `arr` is sorted: |
| 1742 | +
|
| 1743 | + ====== ================================ |
| 1744 | + `side` returned index `i` satisfies |
| 1745 | + ====== ================================ |
| 1746 | + left ``arr[i-1] < value <= self[i]`` |
| 1747 | + right ``arr[i-1] <= value < self[i]`` |
| 1748 | + ====== ================================ |
| 1749 | +
|
| 1750 | + Parameters |
| 1751 | + ---------- |
| 1752 | + arr: array-like |
| 1753 | + Input array. If `sorter` is None, then it must be sorted in |
| 1754 | + ascending order, otherwise `sorter` must be an array of indices |
| 1755 | + that sort it. |
| 1756 | + value : array_like |
| 1757 | + Values to insert into `arr`. |
| 1758 | + side : {'left', 'right'}, optional |
| 1759 | + If 'left', the index of the first suitable location found is given. |
| 1760 | + If 'right', return the last such index. If there is no suitable |
| 1761 | + index, return either 0 or N (where N is the length of `self`). |
| 1762 | + sorter : 1-D array_like, optional |
| 1763 | + Optional array of integer indices that sort array a into ascending |
| 1764 | + order. They are typically the result of argsort. |
| 1765 | +
|
| 1766 | + Returns |
| 1767 | + ------- |
| 1768 | + array of ints |
| 1769 | + Array of insertion points with the same shape as `value`. |
| 1770 | +
|
| 1771 | + See Also |
| 1772 | + -------- |
| 1773 | + numpy.searchsorted : Similar method from NumPy. |
| 1774 | + """ |
| 1775 | + if sorter is not None: |
| 1776 | + sorter = ensure_platform_int(sorter) |
| 1777 | + |
| 1778 | + if isinstance(arr, np.ndarray) and is_integer_dtype(arr) and ( |
| 1779 | + is_integer(value) or is_integer_dtype(value)): |
| 1780 | + from .arrays.array_ import array |
| 1781 | + # if `arr` and `value` have different dtypes, `arr` would be |
| 1782 | + # recast by numpy, causing a slow search. |
| 1783 | + # Before searching below, we therefore try to give `value` the |
| 1784 | + # same dtype as `arr`, while guarding against integer overflows. |
| 1785 | + iinfo = np.iinfo(arr.dtype.type) |
| 1786 | + value_arr = np.array([value]) if is_scalar(value) else np.array(value) |
| 1787 | + if (value_arr >= iinfo.min).all() and (value_arr <= iinfo.max).all(): |
| 1788 | + # value within bounds, so no overflow, so can convert value dtype |
| 1789 | + # to dtype of arr |
| 1790 | + dtype = arr.dtype |
| 1791 | + else: |
| 1792 | + dtype = value_arr.dtype |
| 1793 | + |
| 1794 | + if is_scalar(value): |
| 1795 | + value = dtype.type(value) |
| 1796 | + else: |
| 1797 | + value = array(value, dtype=dtype) |
| 1798 | + elif not (is_object_dtype(arr) or is_numeric_dtype(arr) or |
| 1799 | + is_categorical_dtype(arr)): |
| 1800 | + from pandas.core.series import Series |
| 1801 | + # E.g. if `arr` is an array with dtype='datetime64[ns]' |
| 1802 | + # and `value` is a pd.Timestamp, we may need to convert value |
| 1803 | + value_ser = Series(value)._values |
| 1804 | + value = value_ser[0] if is_scalar(value) else value_ser |
| 1805 | + |
| 1806 | + result = arr.searchsorted(value, side=side, sorter=sorter) |
| 1807 | + return result |
| 1808 | + |
| 1809 | + |
1727 | 1810 | # ---- #
|
1728 | 1811 | # diff #
|
1729 | 1812 | # ---- #
|
|
0 commit comments