Skip to content

Commit 1af6e8b

Browse files
committed
BUG: added series type to wrap_result for empty DataFrame
1 parent 6002d5a commit 1af6e8b

File tree

3 files changed

+32
-14
lines changed

3 files changed

+32
-14
lines changed

doc/source/whatsnew/v0.19.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1563,3 +1563,4 @@ Bug Fixes
15631563
- ``PeriodIndex`` can now accept ``list`` and ``array`` which contains ``pd.NaT`` (:issue:`13430`)
15641564
- Bug in ``df.groupby`` where ``.median()`` returns arbitrary values if grouped dataframe contains empty bins (:issue:`13629`)
15651565
- Bug in ``Index.copy()`` where ``name`` parameter was ignored (:issue:`14302`)
1566+
- Bug in ``_downsample()``. Inconsistent return type on resample of empty DataFrame (:issue:`14962`)

pandas/core/resample.py

+10-5
Original file line numberDiff line numberDiff line change
@@ -697,12 +697,8 @@ def _downsample(self, how, **kwargs):
697697
if not len(ax):
698698
# reset to the new freq
699699
obj = obj.copy()
700-
if how == "size" and isinstance(obj, pd.DataFrame):
701-
obj = obj.groupby(
702-
self.grouper, axis=self.axis).aggregate(how, **kwargs)
703-
704700
obj.index.freq = self.freq
705-
return obj
701+
return self._wrap_result(obj)
706702

707703
# do we have a regular frequency
708704
if ax.freq is not None or ax.inferred_freq is not None:
@@ -773,6 +769,15 @@ def _wrap_result(self, result):
773769
# convert if needed
774770
if self.kind == 'period' and not isinstance(result.index, PeriodIndex):
775771
result.index = result.index.to_period(self.freq)
772+
773+
# Make consistent type of result. GH14962
774+
if not len(self.ax):
775+
grouper = BinGrouper([], result.index)
776+
grouped = self._selected_obj.groupby(grouper)
777+
result = pd.Series([],
778+
index=result.index,
779+
name=grouped.name,
780+
dtype='int64')
776781
return result
777782

778783

pandas/tests/test_resample.py

+21-9
Original file line numberDiff line numberDiff line change
@@ -773,8 +773,18 @@ def test_resample_empty_series(self):
773773
expected = s.copy()
774774
expected.index = s.index._shallow_copy(freq=freq)
775775
assert_index_equal(result.index, expected.index)
776-
assert result.index.freq == expected.index.freq
777-
assert_series_equal(result, expected, check_dtype=False)
776+
777+
self.assertEqual(result.index.freq, expected.index.freq)
778+
779+
if (method == 'size' and
780+
isinstance(result.index, PeriodIndex) and
781+
freq in ['M', 'D']):
782+
# GH12871 - TODO: name should propagate, but currently
783+
# doesn't on lower / same frequency with PeriodIndex
784+
assert_series_equal(result, expected, check_dtype=False)
785+
786+
else:
787+
assert_series_equal(result, expected, check_dtype=False)
778788

779789
def test_resample_empty_dataframe(self):
780790
# GH13212
@@ -783,11 +793,11 @@ def test_resample_empty_dataframe(self):
783793

784794
for freq in ['M', 'D', 'H']:
785795
# count retains dimensions too
786-
methods = downsample_methods + ['count']
796+
methods = downsample_methods + upsample_methods
787797
for method in methods:
788798
result = getattr(f.resample(freq), method)()
789799

790-
expected = f.copy()
800+
expected = pd.Series([])
791801
expected.index = f.index._shallow_copy(freq=freq)
792802
assert_index_equal(result.index, expected.index)
793803
assert result.index.freq == expected.index.freq
@@ -850,11 +860,13 @@ def test_resample_loffset_arg_type(self):
850860

851861
def test_resample_empty_dataframe_with_size(self):
852862
# GH 14962
853-
df1 = pd.DataFrame(dict(a=range(100)),
854-
index=pd.date_range('1/1/2000', periods=100, freq="M"))
855-
df2 = df1[df1.a < 0]
856-
result = df2.resample("Q").size()
857-
assertIsInstance(result, pd.Series)
863+
index = pd.DatetimeIndex([], freq='M')
864+
df = pd.DataFrame([], index=index)
865+
866+
for freq in ['M', 'D', 'H']:
867+
result = df.resample(freq).size()
868+
expected = pd.Series([], index=index, dtype='int64')
869+
assert_series_equal(result, expected)
858870

859871

860872
class TestDatetimeIndex(Base):

0 commit comments

Comments
 (0)