If a user passed an integer N for bins, convert this to a sequence of N equal(ish)-sized bins.
(x_idx: Index, nbins: int, right: bool)
| 394 | |
| 395 | |
| 396 | def _nbins_to_bins(x_idx: Index, nbins: int, right: bool) -> Index: |
| 397 | """ |
| 398 | If a user passed an integer N for bins, convert this to a sequence of N |
| 399 | equal(ish)-sized bins. |
| 400 | """ |
| 401 | if is_scalar(nbins) and nbins < 1: |
| 402 | raise ValueError("`bins` should be a positive integer.") |
| 403 | |
| 404 | if x_idx.size == 0: |
| 405 | raise ValueError("Cannot cut empty array") |
| 406 | |
| 407 | rng = (x_idx.min(), x_idx.max()) |
| 408 | mn, mx = rng |
| 409 | |
| 410 | if is_numeric_dtype(x_idx.dtype) and (np.isinf(mn) or np.isinf(mx)): |
| 411 | # GH#24314 |
| 412 | raise ValueError( |
| 413 | "cannot specify integer `bins` when input data contains infinity" |
| 414 | ) |
| 415 | |
| 416 | if mn == mx: # adjust end points before binning |
| 417 | if _is_dt_or_td(x_idx.dtype): |
| 418 | # using seconds=1 is pretty arbitrary here |
| 419 | # error: Argument 1 to "dtype_to_unit" has incompatible type |
| 420 | # "dtype[Any] | ExtensionDtype"; expected "DatetimeTZDtype | dtype[Any]" |
| 421 | unit = dtype_to_unit(x_idx.dtype) # type: ignore[arg-type] |
| 422 | td = Timedelta(seconds=1).as_unit(cast("TimeUnit", unit)) |
| 423 | # Use DatetimeArray/TimedeltaArray method instead of linspace |
| 424 | # error: Item "ExtensionArray" of "ExtensionArray | ndarray[Any, Any]" |
| 425 | # has no attribute "_generate_range" |
| 426 | bins = x_idx._values._generate_range( # type: ignore[union-attr] |
| 427 | start=mn - td, end=mx + td, periods=nbins + 1, freq=None, unit=unit |
| 428 | ) |
| 429 | else: |
| 430 | mn -= 0.001 * abs(mn) if mn != 0 else 0.001 |
| 431 | mx += 0.001 * abs(mx) if mx != 0 else 0.001 |
| 432 | |
| 433 | bins = np.linspace(mn, mx, nbins + 1, endpoint=True) |
| 434 | else: # adjust end points after binning |
| 435 | if _is_dt_or_td(x_idx.dtype): |
| 436 | # Use DatetimeArray/TimedeltaArray method instead of linspace |
| 437 | |
| 438 | # error: Argument 1 to "dtype_to_unit" has incompatible type |
| 439 | # "dtype[Any] | ExtensionDtype"; expected "DatetimeTZDtype | dtype[Any]" |
| 440 | unit = dtype_to_unit(x_idx.dtype) # type: ignore[arg-type] |
| 441 | # error: Item "ExtensionArray" of "ExtensionArray | ndarray[Any, Any]" |
| 442 | # has no attribute "_generate_range" |
| 443 | bins = x_idx._values._generate_range( # type: ignore[union-attr] |
| 444 | start=mn, end=mx, periods=nbins + 1, freq=None, unit=unit |
| 445 | ) |
| 446 | else: |
| 447 | bins = np.linspace(mn, mx, nbins + 1, endpoint=True) |
| 448 | adj = (mx - mn) * 0.001 # 0.1% of the range |
| 449 | if right: |
| 450 | bins[0] -= adj |
| 451 | else: |
| 452 | bins[-1] += adj |
| 453 |
no test coverage detected