Repository: dask/dask

Issue:
Dataframe operations not working on empty dataframes
```
>>> import dask.dataframe as dd
>>> import pandas as pd
>>> pdf = pd.DataFrame()
>>> ddf = dd.from_pandas(pdf, npartitions=1)
>>> pdf.sum()
Series([], dtype: float64)
>>> ddf.sum().compute()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/ec2-user/.local/lib/python3.6/site-packages/dask/dataframe/core.py", line 1522, in sum
    "sum", axis=axis, skipna=skipna, split_every=split_every, out=out
  File "/home/ec2-user/.local/lib/python3.6/site-packages/dask/dataframe/core.py", line 1490, in _reduction_agg
    result.divisions = (min(self.columns), max(self.columns))
ValueError: min() arg is an empty sequence
>>> pdf.count()
Series([], dtype: int64)
>>> ddf.count().compute()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/ec2-user/.local/lib/python3.6/site-packages/dask/dataframe/core.py", line 1648, in count
    result.divisions = (min(self.columns), max(self.columns))
ValueError: min() arg is an empty sequence
```
Same story for `mean`, `var` and `sem`.
The issue stems from the following line in `dask/dataframe/core.py`:
```
result.divisions = (min(self.columns), max(self.columns))
```



Discussion:

Resolving patch:
diff --git a/dask/dataframe/core.py b/dask/dataframe/core.py
--- a/dask/dataframe/core.py
+++ b/dask/dataframe/core.py
@@ -1491,7 +1491,7 @@ def _reduction_agg(self, name, axis=None, skipna=True, split_every=False, out=No
                 split_every=split_every,
             )
             if isinstance(self, DataFrame):
-                result.divisions = (min(self.columns), max(self.columns))
+                result.divisions = (self.columns.min(), self.columns.max())
             return handle_out(out, result)
 
     @derived_from(pd.DataFrame)
@@ -1641,15 +1641,17 @@ def count(self, axis=None, split_every=False):
             )
         else:
             meta = self._meta_nonempty.count()
+
+            # Need the astype(int) for empty dataframes, which sum to float dtype
             result = self.reduction(
                 M.count,
-                aggregate=M.sum,
+                aggregate=lambda x: x.sum().astype("int64"),
                 meta=meta,
                 token=token,
                 split_every=split_every,
             )
             if isinstance(self, DataFrame):
-                result.divisions = (min(self.columns), max(self.columns))
+                result.divisions = (self.columns.min(), self.columns.max())
             return result
 
     @derived_from(pd.DataFrame)
@@ -1682,7 +1684,7 @@ def mean(self, axis=None, skipna=True, split_every=False, dtype=None, out=None):
                 enforce_metadata=False,
             )
             if isinstance(self, DataFrame):
-                result.divisions = (min(self.columns), max(self.columns))
+                result.divisions = (self.columns.min(), self.columns.max())
             return handle_out(out, result)
 
     @derived_from(pd.DataFrame)
@@ -1723,7 +1725,7 @@ def var(
                 result = self._var_numeric(skipna, ddof, split_every)
 
             if isinstance(self, DataFrame):
-                result.divisions = (min(self.columns), max(self.columns))
+                result.divisions = (self.columns.min(), self.columns.max())
             return handle_out(out, result)
 
     def _var_numeric(self, skipna=True, ddof=1, split_every=False):
@@ -1885,7 +1887,7 @@ def sem(self, axis=None, skipna=None, ddof=1, split_every=False):
             )
 
             if isinstance(self, DataFrame):
-                result.divisions = (min(self.columns), max(self.columns))
+                result.divisions = (self.columns.min(), self.columns.max())
             return result
 
     def quantile(self, q=0.5, axis=0, method="default"):


Test patch:
diff --git a/dask/dataframe/tests/test_arithmetics_reduction.py b/dask/dataframe/tests/test_arithmetics_reduction.py
--- a/dask/dataframe/tests/test_arithmetics_reduction.py
+++ b/dask/dataframe/tests/test_arithmetics_reduction.py
@@ -1346,3 +1346,20 @@ def test_moment():
     ddf = dd.from_pandas(df, npartitions=2)
 
     assert_eq(stats.moment(ddf, 2, 0), scipy.stats.moment(df, 2, 0))
+
+
+@pytest.mark.parametrize("func", ["sum", "count", "mean", "var", "sem"])
+def test_empty_df_reductions(func):
+    pdf = pd.DataFrame()
+    ddf = dd.from_pandas(pdf, npartitions=1)
+
+    dsk_func = getattr(ddf.__class__, func)
+    pd_func = getattr(pdf.__class__, func)
+
+    assert_eq(dsk_func(ddf), pd_func(pdf))
+
+    idx = pd.date_range("2000", periods=4)
+    pdf = pd.DataFrame(index=idx)
+    ddf = dd.from_pandas(pdf, npartitions=1)
+
+    assert_eq(dsk_func(ddf), pd_func(pdf))