|
16 | 16 | from pandas.compat import iteritems, PY2, PY36, OrderedDict |
17 | 17 | from pandas.core.dtypes.generic import ABCSeries, ABCIndex, ABCIndexClass |
18 | 18 | from pandas.core.dtypes.common import (is_integer, is_integer_dtype, |
| 19 | + is_float_dtype, is_object_dtype, |
| 20 | + is_categorical_dtype, |
19 | 21 | is_numeric_dtype, is_number, |
20 | 22 | is_scalar, ensure_platform_int) |
21 | 23 | from pandas.core.dtypes.inference import _iterable_not_string |
@@ -447,10 +449,10 @@ def ensure_within_integer_bounds(value, dtype): |
447 | 449 | ValueError : if value is outside the bounds set in iinfo(dtype) |
448 | 450 | """ |
449 | 451 | if PY2: |
450 | | - # python 2 allows e.g. "a" < 1, avoid this |
| 452 | + # python 2 allows "a" < 1, avoid such nonsense |
451 | 453 | if not (is_number(value) or is_numeric_dtype(value)): |
452 | 454 | msg = "value must be a number, was type {}" |
453 | | - raise ValueError(msg.format(value)) |
| 455 | + raise TypeError(msg.format(value)) |
454 | 456 |
|
455 | 457 | # check if value is within integer bounds |
456 | 458 | iinfo = np.iinfo(dtype) |
@@ -481,24 +483,30 @@ def searchsorted_integer(arr, value, side="left", sorter=None): |
481 | 483 | # but float 2.2 should *not* be converted to int 2 |
482 | 484 | value = np.asarray(value, dtype=dtype) |
483 | 485 |
|
484 | | - return arr.searchsorted(value, side=side, sorter=sorter) |
| 486 | + return np.searchsorted(arr, value, side=side, sorter=sorter) |
485 | 487 |
|
486 | 488 |
|
487 | 489 | def searchsorted(arr, value, side="left", sorter=None): |
488 | 490 | """ |
489 | | - Do a arr.searchsorted(value) with adjustments for dtypes. |
| 491 | + Find indices where elements should be inserted to maintain order. |
490 | 492 |
|
491 | | - :func:`numpy.searchsorted` is only fast if value is of same dtype |
492 | | - as the searched array. Else numpy recasts arr to a higher dtype, which |
493 | | - causes a slowdown. Below we ensure that value has the right dtype |
494 | | - for giving fast results for arr.searchsorted, when possible. |
| 493 | + Find the indices into a sorted array-like `arr` such that, if the |
| 494 | + corresponding elements in `value` were inserted before the indices, |
| 495 | + the order of `arr` would be preserved. |
495 | 496 |
|
496 | | - See :meth:`Index.searchsorted` for details on parameters and return value. |
| 497 | + See :class:`IndexOpsMixin.searchsorted` for more details and examples. |
497 | 498 | """ |
498 | 499 | if sorter is not None: |
499 | 500 | sorter = ensure_platform_int(sorter) |
500 | 501 |
|
501 | 502 | if is_integer_dtype(arr): |
502 | 503 | return searchsorted_integer(arr, value, side=side, sorter=sorter) |
| 504 | + elif (is_object_dtype(arr) or is_float_dtype(arr) or |
| 505 | + is_categorical_dtype(arr)): |
| 506 | + return arr.searchsorted(value, side=side, sorter=sorter) |
503 | 507 | else: |
| 508 | + # fallback solution. E.g. arr is an array with dtype='datetime64[ns]' |
| 509 | + # and value is a pd.Timestamp |
| 510 | + from pandas.core.series import Series |
| 511 | + value = Series(value)._values |
504 | 512 | return arr.searchsorted(value, side=side, sorter=sorter) |
0 commit comments