Skip to content

Commit 6229dbf

Browse files
committed
oweditdomain: improve to time var conversion
1 parent afdb6d7 commit 6229dbf

File tree

2 files changed

+35
-8
lines changed

2 files changed

+35
-8
lines changed

Orange/widgets/data/oweditdomain.py

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2527,8 +2527,16 @@ def mapper(arr, out=None, dtype=dtype, **kwargs):
25272527
def time_parse(values: Sequence[str], name="__"):
25282528
tvar = Orange.data.TimeVariable(name)
25292529
parse_time = ftry(tvar.parse, ValueError, np.nan)
2530-
values = [parse_time(v) for v in values]
2531-
return tvar, values
2530+
_values = [parse_time(v) for v in values]
2531+
if np.all(np.isnan(_values)):
2532+
# try parsing it with pandas (like in transform)
2533+
dti = pd.to_datetime(values, errors="coerce")
2534+
_values = str_to_time(np.array(values))
2535+
date_only = getattr(dti, "_is_dates_only", False)
2536+
if np.all(dti != pd.NaT):
2537+
tvar.have_date = True
2538+
tvar.have_time = not date_only
2539+
return tvar, _values
25322540

25332541

25342542
as_string = np.frompyfunc(str, 1, 1)
@@ -2734,17 +2742,22 @@ def transform(self, c):
27342742
raise TypeError
27352743

27362744

2745+
def str_to_time(data: np.ndarray) -> np.ndarray:
2746+
"""Convert string representation of time into epoch"""
2747+
data = pd.to_datetime(data, errors="coerce").values.astype("M8[us]")
2748+
mask = np.isnat(data)
2749+
data = data.astype(float) / 1e6
2750+
data[mask] = np.nan
2751+
return data
2752+
2753+
27372754
class ReparseTimeTransform(Transformation):
27382755
"""
27392756
Re-parse the column's string repr as datetime.
27402757
"""
27412758
def transform(self, c):
27422759
c = column_str_repr(self.variable, c)
2743-
c = pd.to_datetime(c, errors="coerce").values.astype("M8[us]")
2744-
mask = np.isnat(c)
2745-
orangecol = c.astype(float) / 1e6
2746-
orangecol[mask] = np.nan
2747-
return orangecol
2760+
return str_to_time(c)
27482761

27492762

27502763
class LookupMappingTransform(Transformation):

Orange/widgets/data/tests/test_oweditdomain.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import numpy as np
1010
from numpy.testing import assert_array_equal
11+
import pandas as pd
1112

1213
from AnyQt.QtCore import QItemSelectionModel, Qt, QItemSelection
1314
from AnyQt.QtWidgets import QAction, QComboBox, QLineEdit, \
@@ -33,7 +34,7 @@
3334
table_column_data, ReinterpretVariableEditor, CategoricalVector,
3435
VariableEditDelegate, TransformRole,
3536
RealVector, TimeVector, StringVector, make_dict_mapper, DictMissingConst,
36-
LookupMappingTransform, as_float_or_nan, column_str_repr,
37+
LookupMappingTransform, as_float_or_nan, column_str_repr, time_parse,
3738
GroupItemsDialog)
3839
from Orange.widgets.data.owcolor import OWColor, ColorRole
3940
from Orange.widgets.tests.base import WidgetTest, GuiTest
@@ -917,6 +918,19 @@ def test_column_str_repr(self):
917918
d = column_str_repr(v, np.array([0., np.nan, 1.0]))
918919
assert_array_equal(d, ["00:00:00", "?", "00:00:01"])
919920

921+
def test_time_parse(self):
922+
"""parsing additional datetimes by pandas"""
923+
date = ["1/22/20", "1/23/20", "1/24/20"]
924+
# we use privet method, check if still exists
925+
assert hasattr(pd.DatetimeIndex, '_is_dates_only')
926+
927+
tval, values = time_parse(date)
928+
929+
self.assertTrue(tval.have_date)
930+
self.assertFalse(tval.have_time)
931+
self.assertListEqual(list(values),
932+
[1579651200.0, 1579737600.0, 1579824000.0])
933+
920934

921935
class TestLookupMappingTransform(TestCase):
922936
def setUp(self) -> None:

0 commit comments

Comments
 (0)