-
-
Notifications
You must be signed in to change notification settings - Fork 18.5k
ENH: implement TimedeltaArray/TimedeltaIIndex sum, median, std #28165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
91c5771
7f72b77
2978fa5
ac16d03
7347967
b4c14b3
4c7b4d2
de64d6d
bfc25b9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -143,6 +143,18 @@ def test_setitem_objects(self, obj): | |
|
||
|
||
class TestReductions: | ||
@pytest.mark.parametrize("name", ["sum", "std", "min", "max", "median"]) | ||
@pytest.mark.parametrize("skipna", [True, False]) | ||
def test_reductions_empty(self, name, skipna): | ||
tdi = pd.TimedeltaIndex([]) | ||
arr = tdi.array | ||
|
||
result = getattr(tdi, name)(skipna=skipna) | ||
assert result is pd.NaT | ||
|
||
result = getattr(arr, name)(skipna=skipna) | ||
assert result is pd.NaT | ||
|
||
def test_min_max(self): | ||
arr = TimedeltaArray._from_sequence(["3H", "3H", "NaT", "2H", "5H", "4H"]) | ||
|
||
|
@@ -160,11 +172,87 @@ def test_min_max(self): | |
result = arr.max(skipna=False) | ||
assert result is pd.NaT | ||
|
||
@pytest.mark.parametrize("skipna", [True, False]) | ||
def test_min_max_empty(self, skipna): | ||
arr = TimedeltaArray._from_sequence([]) | ||
result = arr.min(skipna=skipna) | ||
def test_sum(self): | ||
tdi = pd.TimedeltaIndex(["3H", "3H", "NaT", "2H", "5H", "4H"]) | ||
arr = tdi.array | ||
|
||
result = arr.sum(skipna=True) | ||
expected = pd.Timedelta(hours=17) | ||
assert isinstance(result, pd.Timedelta) | ||
WillAyd marked this conversation as resolved.
Show resolved
Hide resolved
|
||
assert result == expected | ||
|
||
result = tdi.sum(skipna=True) | ||
assert isinstance(result, pd.Timedelta) | ||
assert result == expected | ||
|
||
result = arr.sum(skipna=False) | ||
assert result is pd.NaT | ||
|
||
result = tdi.sum(skipna=False) | ||
assert result is pd.NaT | ||
TomAugspurger marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
result = arr.sum(min_count=9) | ||
assert result is pd.NaT | ||
|
||
result = tdi.sum(min_count=9) | ||
assert result is pd.NaT | ||
|
||
result = arr.sum(min_count=1) | ||
assert isinstance(result, pd.Timedelta) | ||
assert result == expected | ||
|
||
result = tdi.sum(min_count=1) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
If we follow the same behaviour as for numerical sum, the result should be 0 instead of NaT There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you're right |
||
assert isinstance(result, pd.Timedelta) | ||
assert result == expected | ||
|
||
def test_npsum(self): | ||
# GH#25335 np.sum should return a Timedelta, not timedelta64 | ||
tdi = pd.TimedeltaIndex(["3H", "3H", "2H", "5H", "4H"]) | ||
arr = tdi.array | ||
|
||
result = np.sum(tdi) | ||
expected = pd.Timedelta(hours=17) | ||
assert isinstance(result, pd.Timedelta) | ||
assert result == expected | ||
|
||
result = np.sum(arr) | ||
assert isinstance(result, pd.Timedelta) | ||
assert result == expected | ||
|
||
def test_std(self): | ||
tdi = pd.TimedeltaIndex(["0H", "4H", "NaT", "4H", "0H", "2H"]) | ||
arr = tdi.array | ||
|
||
result = arr.std(skipna=True) | ||
expected = pd.Timedelta(hours=2) | ||
assert isinstance(result, pd.Timedelta) | ||
assert result == expected | ||
|
||
result = tdi.std(skipna=True) | ||
assert isinstance(result, pd.Timedelta) | ||
assert result == expected | ||
|
||
result = arr.std(skipna=False) | ||
assert result is pd.NaT | ||
|
||
result = tdi.std(skipna=False) | ||
assert result is pd.NaT | ||
|
||
def test_median(self): | ||
tdi = pd.TimedeltaIndex(["0H", "3H", "NaT", "5H06m", "0H", "2H"]) | ||
arr = tdi.array | ||
|
||
result = arr.median(skipna=True) | ||
expected = pd.Timedelta(hours=2) | ||
assert isinstance(result, pd.Timedelta) | ||
assert result == expected | ||
|
||
result = tdi.median(skipna=True) | ||
assert isinstance(result, pd.Timedelta) | ||
assert result == expected | ||
|
||
result = arr.std(skipna=False) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. did you leave these here on purpose (as this tests median)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. looks like a typo, will fix |
||
assert result is pd.NaT | ||
|
||
result = arr.max(skipna=skipna) | ||
result = tdi.std(skipna=False) | ||
assert result is pd.NaT |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Annotations would be nice for new developments, especially where reasonably easy to add
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will do
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like mypy starts complaining about index.py if i add types here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's it saying?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$ mypy pandas/core/arrays/timedeltas.py
pandas/core/indexes/base.py:257: error: Missing return statement