Skip to content

Commit 1996b17

Browse files
authored
BUG: Block.iget not wrapping timedelta64/datetime64 (#31666)
1 parent c3e32d7 commit 1996b17

File tree

3 files changed

+50
-1
lines changed

3 files changed

+50
-1
lines changed

doc/source/whatsnew/v1.0.1.rst

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Fixed regressions
2424
- Fixed regression in :meth:`to_datetime` when parsing non-nanosecond resolution datetimes (:issue:`31491`)
2525
- Fixed regression in :meth:`~DataFrame.to_csv` where specifying an ``na_rep`` might truncate the values written (:issue:`31447`)
2626
- Fixed regression in :class:`Categorical` construction with ``numpy.str_`` categories (:issue:`31499`)
27+
- Fixed regression in :meth:`DataFrame.loc` and :meth:`DataFrame.iloc` when selecting a row containing a single ``datetime64`` or ``timedelta64`` column (:issue:`31649`)
2728
- Fixed regression where setting :attr:`pd.options.display.max_colwidth` was not accepting negative integer. In addition, this behavior has been deprecated in favor of using ``None`` (:issue:`31532`)
2829
- Fixed regression in objTOJSON.c fix return-type warning (:issue:`31463`)
2930
- Fixed regression in :meth:`qcut` when passed a nullable integer. (:issue:`31389`)

pandas/core/internals/blocks.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import numpy as np
99

10-
from pandas._libs import NaT, algos as libalgos, lib, tslib, writers
10+
from pandas._libs import NaT, Timestamp, algos as libalgos, lib, tslib, writers
1111
from pandas._libs.index import convert_scalar
1212
import pandas._libs.internals as libinternals
1313
from pandas._libs.tslibs import Timedelta, conversion
@@ -2158,6 +2158,16 @@ def internal_values(self):
21582158
# Override to return DatetimeArray and TimedeltaArray
21592159
return self.array_values()
21602160

2161+
def iget(self, key):
2162+
# GH#31649 we need to wrap scalars in Timestamp/Timedelta
2163+
# TODO: this can be removed if we ever have 2D EA
2164+
result = super().iget(key)
2165+
if isinstance(result, np.datetime64):
2166+
result = Timestamp(result)
2167+
elif isinstance(result, np.timedelta64):
2168+
result = Timedelta(result)
2169+
return result
2170+
21612171

21622172
class DatetimeBlock(DatetimeLikeBlockMixin, Block):
21632173
__slots__ = ()

pandas/tests/frame/indexing/test_indexing.py

+38
Original file line numberDiff line numberDiff line change
@@ -2165,3 +2165,41 @@ def test_set_reset(self):
21652165

21662166
df = result.set_index("foo")
21672167
tm.assert_index_equal(df.index, idx)
2168+
2169+
2170+
def test_object_casting_indexing_wraps_datetimelike():
2171+
# GH#31649, check the indexing methods all the way down the stack
2172+
df = pd.DataFrame(
2173+
{
2174+
"A": [1, 2],
2175+
"B": pd.date_range("2000", periods=2),
2176+
"C": pd.timedelta_range("1 Day", periods=2),
2177+
}
2178+
)
2179+
2180+
ser = df.loc[0]
2181+
assert isinstance(ser.values[1], pd.Timestamp)
2182+
assert isinstance(ser.values[2], pd.Timedelta)
2183+
2184+
ser = df.iloc[0]
2185+
assert isinstance(ser.values[1], pd.Timestamp)
2186+
assert isinstance(ser.values[2], pd.Timedelta)
2187+
2188+
ser = df.xs(0, axis=0)
2189+
assert isinstance(ser.values[1], pd.Timestamp)
2190+
assert isinstance(ser.values[2], pd.Timedelta)
2191+
2192+
mgr = df._data
2193+
arr = mgr.fast_xs(0)
2194+
assert isinstance(arr[1], pd.Timestamp)
2195+
assert isinstance(arr[2], pd.Timedelta)
2196+
2197+
blk = mgr.blocks[mgr._blknos[1]]
2198+
assert blk.dtype == "M8[ns]" # we got the right block
2199+
val = blk.iget((0, 0))
2200+
assert isinstance(val, pd.Timestamp)
2201+
2202+
blk = mgr.blocks[mgr._blknos[2]]
2203+
assert blk.dtype == "m8[ns]" # we got the right block
2204+
val = blk.iget((0, 0))
2205+
assert isinstance(val, pd.Timedelta)

0 commit comments

Comments
 (0)