Repository: pandas-dev/pandas

Issue:
Resampling and counting empty Series does not have a correct dtype
#### Code Sample, a copy-pastable example if possible

Short examples:

```python
import pandas as pd

a = pd.Series([], dtype="datetime64[ns]", index=pd.DatetimeIndex([]))
print(a.resample("D").size().dtype) # => actual datetime64[ns], expected int64
```
Longer example:

```python
import pandas as pd

t = pd.to_datetime(0)

x = pd.Series([t], index=[t])
print(x.resample("D").size().dtype) # => int64 (OK)

y = x.iloc[0:1]
print(y.resample("D").size().dtype) # => int64 (OK)

z = x.iloc[0:0]
print(z.resample("D").size().dtype) # => actual datetime64[ns], expected int64
```

#### Problem description

When `.resample().size()` an empty dataframe, the resulting dtype is the dtype of the initial Series. It should be an integer.

This means that this kind of things fail if the input `Series` happens to be empty:

```python
monthy_rate = (x.resampe("D").size() > 0).resample("M").mean()
```

#### Expected Output

<pre>
int64
int64
int64
</pre>

#### Output of ``pd.show_versions()``

<details>
INSTALLED VERSIONS
------------------
commit           : None
python           : 3.7.4.final.0
python-bits      : 64
OS               : Linux
OS-release       : 5.2.0-2-amd64
machine          : x86_64
processor        : 
byteorder        : little
LC_ALL           : None
LANG             : fr_FR.utf8
LOCALE           : fr_FR.UTF-8

pandas           : 0.25.1
numpy            : 1.17.2
pytz             : 2019.2
dateutil         : 2.8.0
pip              : 18.1
setuptools       : 40.8.0
Cython           : None
pytest           : None
hypothesis       : None
sphinx           : None
blosc            : None
feather          : None
xlsxwriter       : None
lxml.etree       : None
html5lib         : None
pymysql          : None
psycopg2         : None
jinja2           : None
IPython          : None
pandas_datareader: None
bs4              : None
bottleneck       : None
fastparquet      : None
gcsfs            : None
lxml.etree       : None
matplotlib       : None
numexpr          : None
odfpy            : None
openpyxl         : None
pandas_gbq       : None
pyarrow          : None
pytables         : None
s3fs             : None
scipy            : None
sqlalchemy       : None
tables           : None
xarray           : None
xlrd             : None
xlwt             : None
xlsxwriter       : None
</details>



Discussion:

Resolving patch:
diff --git a/pandas/core/resample.py b/pandas/core/resample.py
--- a/pandas/core/resample.py
+++ b/pandas/core/resample.py
@@ -869,13 +869,32 @@ def var(self, ddof=1, *args, **kwargs):
 
     @Appender(GroupBy.size.__doc__)
     def size(self):
-        # It's a special case as higher level does return
-        # a copy of 0-len objects. GH14962
         result = self._downsample("size")
-        if not len(self.ax) and isinstance(self._selected_obj, ABCDataFrame):
+        if not len(self.ax):
             from pandas import Series
 
-            result = Series([], index=result.index, dtype="int64")
+            if self._selected_obj.ndim == 1:
+                name = self._selected_obj.name
+            else:
+                name = None
+            result = Series([], index=result.index, dtype="int64", name=name)
+        return result
+
+    @Appender(GroupBy.count.__doc__)
+    def count(self):
+        result = self._downsample("count")
+        if not len(self.ax):
+            if self._selected_obj.ndim == 1:
+                result = self._selected_obj.__class__(
+                    [], index=result.index, dtype="int64", name=self._selected_obj.name
+                )
+            else:
+                from pandas import DataFrame
+
+                result = DataFrame(
+                    [], index=result.index, columns=result.columns, dtype="int64"
+                )
+
         return result
 
     def quantile(self, q=0.5, **kwargs):
@@ -923,14 +942,6 @@ def g(self, _method=method, *args, **kwargs):
     g.__doc__ = getattr(GroupBy, method).__doc__
     setattr(Resampler, method, g)
 
-# groupby & aggregate methods
-for method in ["count"]:
-
-    def h(self, _method=method):
-        return self._downsample(_method)
-
-    h.__doc__ = getattr(GroupBy, method).__doc__
-    setattr(Resampler, method, h)
 
 # series only methods
 for method in ["nunique"]:


Test patch:
diff --git a/pandas/tests/resample/test_base.py b/pandas/tests/resample/test_base.py
--- a/pandas/tests/resample/test_base.py
+++ b/pandas/tests/resample/test_base.py
@@ -112,6 +112,22 @@ def test_resample_empty_series(freq, empty_series, resample_method):
     tm.assert_series_equal(result, expected, check_dtype=False)
 
 
+@all_ts
+@pytest.mark.parametrize("freq", ["M", "D", "H"])
+@pytest.mark.parametrize("resample_method", ["count", "size"])
+def test_resample_count_empty_series(freq, empty_series, resample_method):
+    # GH28427
+    result = getattr(empty_series.resample(freq), resample_method)()
+
+    if isinstance(empty_series.index, PeriodIndex):
+        index = empty_series.index.asfreq(freq=freq)
+    else:
+        index = empty_series.index._shallow_copy(freq=freq)
+    expected = pd.Series([], dtype="int64", index=index, name=empty_series.name)
+
+    tm.assert_series_equal(result, expected)
+
+
 @all_ts
 @pytest.mark.parametrize("freq", ["M", "D", "H"])
 def test_resample_empty_dataframe(empty_frame, freq, resample_method):
@@ -136,6 +152,44 @@ def test_resample_empty_dataframe(empty_frame, freq, resample_method):
     # test size for GH13212 (currently stays as df)
 
 
+@all_ts
+@pytest.mark.parametrize("freq", ["M", "D", "H"])
+def test_resample_count_empty_dataframe(freq, empty_frame):
+    # GH28427
+
+    empty_frame = empty_frame.copy()
+    empty_frame["a"] = []
+
+    result = empty_frame.resample(freq).count()
+
+    if isinstance(empty_frame.index, PeriodIndex):
+        index = empty_frame.index.asfreq(freq=freq)
+    else:
+        index = empty_frame.index._shallow_copy(freq=freq)
+    expected = pd.DataFrame({"a": []}, dtype="int64", index=index)
+
+    tm.assert_frame_equal(result, expected)
+
+
+@all_ts
+@pytest.mark.parametrize("freq", ["M", "D", "H"])
+def test_resample_size_empty_dataframe(freq, empty_frame):
+    # GH28427
+
+    empty_frame = empty_frame.copy()
+    empty_frame["a"] = []
+
+    result = empty_frame.resample(freq).size()
+
+    if isinstance(empty_frame.index, PeriodIndex):
+        index = empty_frame.index.asfreq(freq=freq)
+    else:
+        index = empty_frame.index._shallow_copy(freq=freq)
+    expected = pd.Series([], dtype="int64", index=index)
+
+    tm.assert_series_equal(result, expected)
+
+
 @pytest.mark.parametrize("index", tm.all_timeseries_index_generator(0))
 @pytest.mark.parametrize("dtype", [np.float, np.int, np.object, "datetime64[ns]"])
 def test_resample_empty_dtypes(index, dtype, resample_method):