Skip to content
16 changes: 16 additions & 0 deletions pandas/core/arrays/datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,22 @@ def tz_localize(self, tz, ambiguous='raise', errors='raise'):
# ----------------------------------------------------------------
# Conversion Methods - Vectorized analogues of Timestamp methods

def to_datetime64(self):
"""
Return numpy datetime64[ns] representation of self. For timezone-aware
cases, the returned array represents UTC timestamps.

Returns
-------
ndarray[datetime64[ns]]
"""
return self.asi8.view('M8[ns]')

@property
def asm8(self):
"""Vectorized analogue of Timestamp.asm8"""
return self.to_datetime64()

def to_pydatetime(self):
"""
Return Datetime Array/Index as object ndarray of datetime.datetime
Expand Down
25 changes: 25 additions & 0 deletions pandas/core/arrays/timedeltas.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,31 @@ def to_pytimedelta(self):
"""
return tslibs.ints_to_pytimedelta(self.asi8)

def to_timedelta64(self):
"""
Return numpy array with timedelta64[ns] dtype

Returns
-------
ndarray[timedelta64[ns]]

Notes
-----
This returns a view on self, not a copy.

See also
--------
Timedelta.to_timedelta64
"""
return self.asi8.view('m8[ns]')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are going a little bit in circles here, as asi8 itself is already self.values.view('i8') ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find asi8 much more explicit than alues (BTW as I mentioned to jreback the "v" key on my keyboard is sticky; I'm going to stop copy-pasting and let you guys infer the missing letter for a while).


@property
def asm8(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need both to_timedelta64 and asm8 ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we were starting fresh I would say no, but as it is I think consistency with the scalar type is really worthwhile. (and to your point aboe DatetimeIndex should have a to_datetime64 method)

"""
Vectorized analogue of Timedelta.asm8
"""
return self.to_timedelta64()

days = _field_accessor("days", "days",
" Number of days for each element. ")
seconds = _field_accessor("seconds", "seconds",
Expand Down
48 changes: 48 additions & 0 deletions pandas/tests/arrays/test_datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,30 @@ def test_to_period(self, datetime_index, freqstr):
# an EA-specific tm.assert_ function
tm.assert_index_equal(pd.Index(result), pd.Index(expected))

def test_asm8(self, datetime_index):
dti = datetime_index
arr = DatetimeArrayMixin(dti)

expected = np.array([x.asm8 for x in dti], dtype='M8[ns]')

result = dti.asm8
tm.assert_numpy_array_equal(result, expected)

result = arr.asm8
tm.assert_numpy_array_equal(result, expected)

def test_to_datetime64(self, datetime_index):
dti = datetime_index
arr = DatetimeArrayMixin(dti)

expected = np.array([x.asm8 for x in dti], dtype='M8[ns]')

result = dti.to_datetime64()
tm.assert_numpy_array_equal(result, expected)

result = arr.to_datetime64()
tm.assert_numpy_array_equal(result, expected)

@pytest.mark.parametrize('propname', pd.DatetimeIndex._bool_ops)
def test_bool_properties(self, datetime_index, propname):
# in this case _bool_ops is just `is_leap_year`
Expand Down Expand Up @@ -148,6 +172,30 @@ def test_astype_object(self):
assert asobj.dtype == 'O'
assert list(asobj) == list(tdi)

def test_asm8(self):
tdi = pd.TimedeltaIndex(['1 Hour', '3 Hours'])
arr = TimedeltaArrayMixin(tdi)

expected = np.array([3600, 10800], dtype='m8[ns]') * 1e9

result = tdi.asm8
tm.assert_numpy_array_equal(result, expected)

result = arr.asm8
tm.assert_numpy_array_equal(result, expected)

def test_to_timedelta64(self):
tdi = pd.TimedeltaIndex(['1 Hour', '3 Hours'])
arr = TimedeltaArrayMixin(tdi)

expected = np.array([3600, 10800], dtype='m8[ns]') * 1e9

result = tdi.to_timedelta64()
tm.assert_numpy_array_equal(result, expected)

result = arr.to_timedelta64()
tm.assert_numpy_array_equal(result, expected)

def test_to_pytimedelta(self, timedelta_index):
tdi = timedelta_index
arr = TimedeltaArrayMixin(tdi)
Expand Down