|
4 | 4 | import numpy as np
|
5 | 5 |
|
6 | 6 | from pandas._libs import index as libindex
|
7 |
| -from pandas._libs.tslibs import NaT, frequencies as libfrequencies, iNaT, resolution |
| 7 | +from pandas._libs.tslibs import NaT, frequencies as libfrequencies, resolution |
8 | 8 | from pandas._libs.tslibs.period import Period
|
9 | 9 | from pandas.util._decorators import Appender, Substitution, cache_readonly
|
10 | 10 |
|
|
17 | 17 | is_float_dtype,
|
18 | 18 | is_integer,
|
19 | 19 | is_integer_dtype,
|
| 20 | + is_list_like, |
20 | 21 | is_object_dtype,
|
21 | 22 | pandas_dtype,
|
22 | 23 | )
|
|
42 | 43 | )
|
43 | 44 | from pandas.core.indexes.datetimes import DatetimeIndex, Index
|
44 | 45 | from pandas.core.indexes.numeric import Int64Index
|
45 |
| -from pandas.core.missing import isna |
46 | 46 | from pandas.core.ops import get_op_result_name
|
47 | 47 | from pandas.core.tools.datetimes import DateParseError, parse_time_string
|
48 | 48 |
|
@@ -507,42 +507,43 @@ def get_value(self, series, key):
|
507 | 507 | Fast lookup of value from 1-dimensional ndarray. Only use this if you
|
508 | 508 | know what you're doing
|
509 | 509 | """
|
510 |
| - s = com.values_from_object(series) |
511 |
| - try: |
512 |
| - value = super().get_value(s, key) |
513 |
| - except (KeyError, IndexError): |
514 |
| - if isinstance(key, str): |
515 |
| - asdt, parsed, reso = parse_time_string(key, self.freq) |
516 |
| - grp = resolution.Resolution.get_freq_group(reso) |
517 |
| - freqn = resolution.get_freq_group(self.freq) |
518 |
| - |
519 |
| - vals = self._ndarray_values |
520 |
| - |
521 |
| - # if our data is higher resolution than requested key, slice |
522 |
| - if grp < freqn: |
523 |
| - iv = Period(asdt, freq=(grp, 1)) |
524 |
| - ord1 = iv.asfreq(self.freq, how="S").ordinal |
525 |
| - ord2 = iv.asfreq(self.freq, how="E").ordinal |
526 |
| - |
527 |
| - if ord2 < vals[0] or ord1 > vals[-1]: |
528 |
| - raise KeyError(key) |
529 |
| - |
530 |
| - pos = np.searchsorted(self._ndarray_values, [ord1, ord2]) |
531 |
| - key = slice(pos[0], pos[1] + 1) |
532 |
| - return series[key] |
533 |
| - elif grp == freqn: |
534 |
| - key = Period(asdt, freq=self.freq).ordinal |
535 |
| - return com.maybe_box( |
536 |
| - self, self._int64index.get_value(s, key), series, key |
537 |
| - ) |
538 |
| - else: |
| 510 | + if is_integer(key): |
| 511 | + return series.iat[key] |
| 512 | + |
| 513 | + if isinstance(key, str): |
| 514 | + asdt, parsed, reso = parse_time_string(key, self.freq) |
| 515 | + grp = resolution.Resolution.get_freq_group(reso) |
| 516 | + freqn = resolution.get_freq_group(self.freq) |
| 517 | + |
| 518 | + vals = self._ndarray_values |
| 519 | + |
| 520 | + # if our data is higher resolution than requested key, slice |
| 521 | + if grp < freqn: |
| 522 | + iv = Period(asdt, freq=(grp, 1)) |
| 523 | + ord1 = iv.asfreq(self.freq, how="S").ordinal |
| 524 | + ord2 = iv.asfreq(self.freq, how="E").ordinal |
| 525 | + |
| 526 | + if ord2 < vals[0] or ord1 > vals[-1]: |
539 | 527 | raise KeyError(key)
|
540 | 528 |
|
541 |
| - period = Period(key, self.freq) |
542 |
| - key = period.value if isna(period) else period.ordinal |
543 |
| - return com.maybe_box(self, self._int64index.get_value(s, key), series, key) |
544 |
| - else: |
545 |
| - return com.maybe_box(self, value, series, key) |
| 529 | + pos = np.searchsorted(self._ndarray_values, [ord1, ord2]) |
| 530 | + key = slice(pos[0], pos[1] + 1) |
| 531 | + return series[key] |
| 532 | + elif grp == freqn: |
| 533 | + key = Period(asdt, freq=self.freq) |
| 534 | + loc = self.get_loc(key) |
| 535 | + return series.iloc[loc] |
| 536 | + else: |
| 537 | + raise KeyError(key) |
| 538 | + |
| 539 | + elif isinstance(key, Period) or key is NaT: |
| 540 | + ordinal = key.ordinal if key is not NaT else NaT.value |
| 541 | + loc = self._engine.get_loc(ordinal) |
| 542 | + return series[loc] |
| 543 | + |
| 544 | + # slice, PeriodIndex, np.ndarray, List[Period] |
| 545 | + value = Index.get_value(self, series, key) |
| 546 | + return com.maybe_box(self, value, series, key) |
546 | 547 |
|
547 | 548 | @Appender(_index_shared_docs["get_indexer"] % _index_doc_kwargs)
|
548 | 549 | def get_indexer(self, target, method=None, limit=None, tolerance=None):
|
@@ -579,36 +580,52 @@ def get_indexer_non_unique(self, target):
|
579 | 580 |
|
580 | 581 | def get_loc(self, key, method=None, tolerance=None):
|
581 | 582 | """
|
582 |
| - Get integer location for requested label |
| 583 | + Get integer location for requested label. |
| 584 | +
|
| 585 | + Parameters |
| 586 | + ---------- |
| 587 | + key : Period, NaT, str, or datetime |
| 588 | + String or datetime key must be parseable as Period. |
583 | 589 |
|
584 | 590 | Returns
|
585 | 591 | -------
|
586 |
| - loc : int |
| 592 | + loc : int or ndarray[int64] |
| 593 | +
|
| 594 | + Raises |
| 595 | + ------ |
| 596 | + KeyError |
| 597 | + Key is not present in the index. |
| 598 | + TypeError |
| 599 | + If key is listlike or otherwise not hashable. |
587 | 600 | """
|
588 |
| - try: |
589 |
| - return self._engine.get_loc(key) |
590 |
| - except KeyError: |
591 |
| - if is_integer(key): |
592 |
| - raise |
593 | 601 |
|
| 602 | + if isinstance(key, str): |
594 | 603 | try:
|
595 | 604 | asdt, parsed, reso = parse_time_string(key, self.freq)
|
596 | 605 | key = asdt
|
597 |
| - except TypeError: |
598 |
| - pass |
599 | 606 | except DateParseError:
|
600 | 607 | # A string with invalid format
|
601 | 608 | raise KeyError(f"Cannot interpret '{key}' as period")
|
602 | 609 |
|
603 |
| - try: |
604 |
| - key = Period(key, freq=self.freq) |
605 |
| - except ValueError: |
606 |
| - # we cannot construct the Period |
607 |
| - # as we have an invalid type |
608 |
| - raise KeyError(key) |
| 610 | + elif is_integer(key): |
| 611 | + # Period constructor will cast to string, which we dont want |
| 612 | + raise KeyError(key) |
| 613 | + |
| 614 | + try: |
| 615 | + key = Period(key, freq=self.freq) |
| 616 | + except ValueError: |
| 617 | + # we cannot construct the Period |
| 618 | + # as we have an invalid type |
| 619 | + if is_list_like(key): |
| 620 | + raise TypeError(f"'{key}' is an invalid key") |
| 621 | + raise KeyError(key) |
| 622 | + |
| 623 | + ordinal = key.ordinal if key is not NaT else key.value |
| 624 | + try: |
| 625 | + return self._engine.get_loc(ordinal) |
| 626 | + except KeyError: |
609 | 627 |
|
610 | 628 | try:
|
611 |
| - ordinal = iNaT if key is NaT else key.ordinal |
612 | 629 | if tolerance is not None:
|
613 | 630 | tolerance = self._convert_tolerance(tolerance, np.asarray(key))
|
614 | 631 | return self._int64index.get_loc(ordinal, method, tolerance)
|
|
0 commit comments