Skip to content

Commit 7f36e67

Browse files
committed
List indexer on PeriodIndex doesn't coerce strings (pandas-dev#11278)
1 parent cde73af commit 7f36e67

File tree

3 files changed

+55
-2
lines changed

3 files changed

+55
-2
lines changed

doc/source/whatsnew/v1.0.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,7 @@ Indexing
778778
- Bug when indexing with ``.loc`` where the index was a :class:`CategoricalIndex` with non-string categories didn't work (:issue:`17569`, :issue:`30225`)
779779
- :meth:`Index.get_indexer_non_unique` could fail with `TypeError` in some cases, such as when searching for ints in a string index (:issue:`28257`)
780780
- Bug in :meth:`Float64Index.get_loc` incorrectly raising ``TypeError`` instead of ``KeyError`` (:issue:`29189`)
781+
- List datetime string indexer could fail on `PeriodIndex` or `DatetimeIndex` (:issue:`11278`)
781782

782783
Missing
783784
^^^^^^^

pandas/core/indexing.py

+25-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from pandas._libs.indexing import _NDFrameIndexerBase
66
from pandas._libs.lib import item_from_zerodim
7+
from pandas._libs.tslibs import Period, Timestamp
78
from pandas.errors import AbstractMethodError
89
from pandas.util._decorators import Appender
910

@@ -18,7 +19,13 @@
1819
is_sparse,
1920
)
2021
from pandas.core.dtypes.concat import concat_compat
21-
from pandas.core.dtypes.generic import ABCDataFrame, ABCMultiIndex, ABCSeries
22+
from pandas.core.dtypes.generic import (
23+
ABCDataFrame,
24+
ABCDatetimeIndex,
25+
ABCMultiIndex,
26+
ABCPeriodIndex,
27+
ABCSeries,
28+
)
2229
from pandas.core.dtypes.missing import _infer_fill_value, isna
2330

2431
import pandas.core.common as com
@@ -1660,6 +1667,23 @@ def _get_partial_string_timestamp_match_key(self, key, labels):
16601667
new_key.append(component)
16611668
key = tuple(new_key)
16621669

1670+
elif isinstance(labels, (ABCDatetimeIndex, ABCPeriodIndex)):
1671+
if isinstance(key, list) and len(key) == 2:
1672+
object_type_mapper = {"period": Period, "datetime64": Timestamp}
1673+
object_type = labels.inferred_type
1674+
freq_str = labels.freqstr
1675+
1676+
for i, comp in enumerate(key):
1677+
try:
1678+
"""
1679+
if labels type is period and labels freq is 'D'
1680+
'2019-12-27' to Period('2019-12-27', 'D')
1681+
"""
1682+
key[i] = object_type_mapper[object_type](comp, freq=freq_str)
1683+
1684+
except (TypeError, ValueError, KeyError):
1685+
pass
1686+
16631687
return key
16641688

16651689
def _getitem_axis(self, key, axis: int):

pandas/tests/indexing/test_loc.py

+29-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import pytest
77

88
import pandas as pd
9-
from pandas import DataFrame, Series, Timestamp, date_range
9+
from pandas import DataFrame, Period, Series, Timestamp, date_range, period_range
1010
from pandas.api.types import is_scalar
1111
from pandas.tests.indexing.common import Base
1212
import pandas.util.testing as tm
@@ -939,6 +939,34 @@ def test_loc_reverse_assignment(self):
939939

940940
tm.assert_series_equal(result, expected)
941941

942+
@pytest.mark.parametrize(
943+
"idx,labels,expected_idx",
944+
[
945+
(
946+
period_range(start="2000", periods=20, freq="D"),
947+
["1/4/2000", "1/8/2000"],
948+
[Period("1/4/2000", freq="D"), Period("1/8/2000", freq="D")],
949+
),
950+
(
951+
date_range(start="2000", periods=20, freq="D"),
952+
["1/4/2000", "1/8/2000"],
953+
[Timestamp("1/4/2000", freq="D"), Timestamp("1/8/2000", freq="D")],
954+
),
955+
],
956+
)
957+
def test_loc_with_datetime_string_list(self, idx, labels, expected_idx):
958+
# GH 11278
959+
s = Series(range(20), index=idx)
960+
df = DataFrame(range(20), index=idx)
961+
962+
expected_value = [3, 7]
963+
expected_s = Series(expected_value, expected_idx)
964+
expected_df = DataFrame(expected_value, expected_idx)
965+
966+
tm.assert_series_equal(expected_s, s.loc[labels])
967+
tm.assert_series_equal(expected_s, s[labels])
968+
tm.assert_frame_equal(expected_df, df.loc[labels])
969+
942970

943971
def test_series_loc_getitem_label_list_missing_values():
944972
# gh-11428

0 commit comments

Comments
 (0)