Skip to content

Commit 1c65b96

Browse files
committed
Speed up DatetimeConverter by using Matplotlib's epoch2num when possible.
1 parent 4216178 commit 1c65b96

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

pandas/tseries/converter.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,10 @@ def _dt_to_float_ordinal(dt):
144144
preserving hours, minutes, seconds and microseconds. Return value
145145
is a :func:`float`.
146146
"""
147-
base = dates.date2num(dt)
147+
if isinstance(dt, np.ndarray) and com.is_datetime64_ns_dtype(dt):
148+
base = dates.epoch2num(dt.astype(np.int64) / 1.0E9)
149+
else:
150+
base = dates.date2num(dt)
148151
return base
149152

150153

pandas/tseries/tests/test_converter.py

+42
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@
55
import nose
66

77
import numpy as np
8+
from numpy.testing import assert_almost_equal as np_assert_almost_equal
9+
from pandas import Timestamp
810
from pandas.compat import u
911
import pandas.util.testing as tm
12+
from pandas.tseries.offsets import Second, Milli, Micro
1013

1114
try:
1215
import pandas.tseries.converter as converter
@@ -46,9 +49,48 @@ def test_conversion(self):
4649
rs = self.dtc.convert('2012-1-1', None, None)
4750
self.assertEqual(rs, xp)
4851

52+
rs = self.dtc.convert(Timestamp('2012-1-1'), None, None)
53+
self.assertEqual(rs, xp)
54+
55+
def test_conversion_float(self):
56+
decimals = 9
57+
58+
rs = self.dtc.convert(Timestamp('2012-1-1 01:02:03', tz='UTC'), None, None)
59+
xp = converter.dates.date2num(Timestamp('2012-1-1 01:02:03', tz='UTC'))
60+
np_assert_almost_equal(rs, xp, decimals)
61+
62+
rs = self.dtc.convert(Timestamp('2012-1-1 09:02:03', tz='Asia/Hong_Kong'), None, None)
63+
np_assert_almost_equal(rs, xp, decimals)
64+
65+
rs = self.dtc.convert(datetime(2012, 1, 1, 1, 2, 3), None, None)
66+
np_assert_almost_equal(rs, xp, decimals)
67+
4968
def test_time_formatter(self):
5069
self.tc(90000)
5170

71+
def test_dateindex_conversion(self):
72+
decimals = 9
73+
74+
for freq in ('B', 'L', 'S'):
75+
dateindex = tm.makeDateIndex(k = 10, freq = freq)
76+
rs = self.dtc.convert(dateindex, None, None)
77+
xp = converter.dates.date2num(dateindex)
78+
np_assert_almost_equal(rs, xp, decimals)
79+
80+
def test_resolution(self):
81+
def _assert_less(ts1, ts2):
82+
val1 = self.dtc.convert(ts1, None, None)
83+
val2 = self.dtc.convert(ts2, None, None)
84+
if not val1 < val2:
85+
raise AssertionError('{0} is not less than {1}.'.format(val1, val2))
86+
87+
# Matplotlib's time representation using floats cannot distinguish intervals smaller
88+
# than ~10 microsecond in the common range of years.
89+
ts = Timestamp('2012-1-1')
90+
_assert_less(ts, ts + Second())
91+
_assert_less(ts, ts + Milli())
92+
_assert_less(ts, ts + Micro(50))
93+
5294

5395
if __name__ == '__main__':
5496
import nose

0 commit comments

Comments
 (0)