Repository: dask/dask

Issue:
Count aggregate fails on simple DataFrame
An equivalent example with just Pandas seems to work fine, so I'm not sure what I'm doing wrong here. Could this be an actual bug?

```python
import pandas as pd
import dask.dataframe as dd
ddf_broken = dd.from_pandas(
    pd.DataFrame([1, 2]),
    npartitions=1,
)
ddf_broken.groupby(
    ddf_broken.index
).aggregate('count').compute()
```

```
...
  File "/Users/justusperlwitz/jupyter-notes/env/lib/python3.6/site-packages/pandas/core/generic.py", line 5162, in groupby
    **kwargs)
  File "/Users/justusperlwitz/jupyter-notes/env/lib/python3.6/site-packages/pandas/core/groupby.py", line 1759, in groupby
    return klass(obj, by, **kwds)
  File "/Users/justusperlwitz/jupyter-notes/env/lib/python3.6/site-packages/pandas/core/groupby.py", line 392, in __init__
    mutated=self.mutated)
  File "/Users/justusperlwitz/jupyter-notes/env/lib/python3.6/site-packages/pandas/core/groupby.py", line 2863, in _get_grouper
    if not isinstance(gpr, Grouping) else gpr
  File "/Users/justusperlwitz/jupyter-notes/env/lib/python3.6/site-packages/pandas/core/groupby.py", line 2538, in __init__
    self.grouper = _convert_grouper(index, grouper)
  File "/Users/justusperlwitz/jupyter-notes/env/lib/python3.6/site-packages/pandas/core/groupby.py", line 2891, in _convert_grouper
    raise ValueError('Grouper and axis must be same length')
```

```bash
$ pip freeze | grep -e dask -e pandas
dask==0.16.0
pandas==0.21.0
```


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
@@ -2966,7 +2966,11 @@ def elemwise(op, *args, **kwargs):
             # should not occur in current funcs
             msg = 'elemwise with 2 or more DataFrames and Scalar is not supported'
             raise NotImplementedError(msg)
-        meta = _emulate(op, *args, **kwargs)
+        # For broadcastable series, use no rows.
+        parts = [d._meta if _is_broadcastable(d)
+                 else d._meta_nonempty for d in dasks]
+        with raise_on_meta_error(funcname(op)):
+            meta = partial_by_order(*parts, function=op, other=other)
 
     return new_dd_object(dsk, _name, meta, divisions)
 
@@ -3152,9 +3156,9 @@ def apply_concat_apply(args, chunk=None, aggregate=None, combine=None,
             dsk[(b, j)] = (aggregate, conc)
 
     if meta is no_default:
-        meta_chunk = _emulate(apply, chunk, args, chunk_kwargs)
-        meta = _emulate(apply, aggregate, [_concat([meta_chunk])],
-                        aggregate_kwargs)
+        meta_chunk = _emulate(chunk, *args, **chunk_kwargs)
+        meta = _emulate(aggregate, _concat([meta_chunk]),
+                        **aggregate_kwargs)
     meta = make_meta(meta)
 
     for arg in args:
@@ -3173,15 +3177,8 @@ def _extract_meta(x, nonempty=False):
     """
     Extract internal cache data (``_meta``) from dd.DataFrame / dd.Series
     """
-    if isinstance(x, Scalar):
+    if isinstance(x, (Scalar, _Frame)):
         return x._meta_nonempty if nonempty else x._meta
-    elif isinstance(x, _Frame):
-        if (isinstance(x, Series) and
-                x.npartitions == 1 and
-                x.known_divisions):  # may be broadcastable
-            return x._meta
-        else:
-            return x._meta_nonempty if nonempty else x._meta
     elif isinstance(x, list):
         return [_extract_meta(_x, nonempty) for _x in x]
     elif isinstance(x, tuple):


Test patch:
diff --git a/dask/dataframe/tests/test_dataframe.py b/dask/dataframe/tests/test_dataframe.py
--- a/dask/dataframe/tests/test_dataframe.py
+++ b/dask/dataframe/tests/test_dataframe.py
@@ -519,6 +519,22 @@ def f(s, x=1):
     assert a.x.map_partitions(f, x=5)._name != a.x.map_partitions(f, x=6)._name
 
 
+def test_metadata_inference_single_partition_aligned_args():
+    # https://github.com/dask/dask/issues/3034
+    # Previously broadcastable series functionality broke this
+
+    df = pd.DataFrame({'x': [1, 2, 3, 4, 5]})
+    ddf = dd.from_pandas(df, npartitions=1)
+
+    def check(df, df_x):
+        assert len(df) == len(df_x)
+        assert len(df) > 0
+        return df
+
+    res = dd.map_partitions(check, ddf, ddf.x)
+    assert_eq(res, ddf)
+
+
 def test_drop_duplicates():
     res = d.drop_duplicates()
     res2 = d.drop_duplicates(split_every=2)