# Buggy code
def _gen_dataframe_chunks(splits, out_shape, left_or_right, df):
    out_chunks = []
    if splits.all_axes_can_split():
        # no shuffle for all axes
        kw = {
            "index_shuffle_size": -1 if splits[0].isdummy() else None,
            "column_shuffle_size": -1 if splits[1].isdummy() else None,
        }
        for out_idx in itertools.product(*(range(s) for s in out_shape)):
            row_idx = splits.get_axis_idx(0, left_or_right, out_idx[0])
            col_idx = splits.get_axis_idx(1, left_or_right, out_idx[1])
            index_min_max = splits.get_axis_split(0, left_or_right, out_idx[0])
            column_min_max = splits.get_axis_split(1, left_or_right, out_idx[1])
            chunk = df.cix[row_idx, col_idx]
            if _need_align_map(
                chunk,
                index_min_max,
                column_min_max,
                splits[0].isdummy(),
                splits[1].isdummy(),
            ):
                if splits[1].isdummy():
                    dtypes = chunk.dtypes
                else:
                    dtypes = filter_dtypes(chunk.dtypes, column_min_max)
                chunk_kw = {
                    "index_value": chunk.index_value if splits[0].isdummy() else None,
                    "columns_value": chunk.columns if splits[1].isdummy() else None,
                }
                align_op = DataFrameIndexAlignMap(
                    index_min_max=index_min_max,
                    column_min_max=column_min_max,
                    dtypes=dtypes,
                    sparse=chunk.issparse(),
                    object_type=ObjectType.dataframe,
                    **kw,
                )
                out_chunk = align_op.new_chunk(
                    [chunk], shape=(np.nan, np.nan), index=out_idx, **chunk_kw
                )
            else:
                out_chunk = chunk
            out_chunks.append(out_chunk)
    elif splits.one_axis_can_split():
        # one axis needs shuffle
        shuffle_axis = 0 if splits[0] is None else 1
        align_axis = 1 - shuffle_axis

        for align_axis_idx in range(out_shape[align_axis]):
            if align_axis == 0:
                kw = {
                    "index_min_max": splits.get_axis_split(
                        align_axis, left_or_right, align_axis_idx
                    ),
                    "index_shuffle_size": -1 if splits[0].isdummy() else None,
                    "column_shuffle_size": out_shape[shuffle_axis],
                }
                input_idx = splits.get_axis_idx(
                    align_axis, left_or_right, align_axis_idx
                )
            else:
                kw = {
                    "column_min_max": splits.get_axis_split(
                        align_axis, left_or_right, align_axis_idx
                    ),
                    "index_shuffle_size": out_shape[shuffle_axis],
                    "column_shuffle_size": -1 if splits[1].isdummy() else None,
                }
                input_idx = splits.get_axis_idx(
                    align_axis, left_or_right, align_axis_idx
                )
            input_chunks = [c for c in df.chunks if c.index[align_axis] == input_idx]
            map_chunks = []
            for j, input_chunk in enumerate(input_chunks):
                chunk_kw = dict()
                if align_axis == 0:
                    chunk_kw["index_value"] = (
                        input_chunk.index_value if splits[0].isdummy() else None
                    )
                else:
                    chunk_kw["columns_value"] = (
                        input_chunk.columns if splits[1].isdummy() else None
                    )
                map_op = DataFrameIndexAlignMap(
                    sparse=input_chunk.issparse(),
                    object_type=ObjectType.dataframe,
                    **kw,
                )
                idx = [None, None]
                idx[align_axis] = align_axis_idx
                idx[shuffle_axis] = j
                map_chunks.append(
                    map_op.new_chunk(
                        [input_chunk],
                        shape=(np.nan, np.nan),
                        index=tuple(idx),
                        **chunk_kw,
                    )
                )
            proxy_chunk = DataFrameShuffleProxy(
                sparse=df.issparse(), object_type=ObjectType.dataframe
            ).new_chunk(map_chunks, shape=())
            for j in range(out_shape[shuffle_axis]):
                chunk_kw = dict()
                if align_axis == 0:
                    chunk_kw["index_value"] = (
                        proxy_chunk.inputs[0].inputs[0].index_value
                        if splits[0].isdummy()
                        else None
                    )
                else:
                    chunk_kw["columns_value"] = (
                        proxy_chunk.inputs[0].inputs[0].columns
                        if splits[1].isdummy()
                        else None
                    )
                reduce_idx = (
                    (align_axis_idx, j) if align_axis == 0 else (j, align_axis_idx)
                )
                reduce_op = DataFrameIndexAlignReduce(
                    i=j,
                    sparse=proxy_chunk.issparse(),
                    shuffle_key=",".join(str(idx) for idx in reduce_idx),
                    object_type=ObjectType.dataframe,
                )
                out_chunks.append(
                    reduce_op.new_chunk(
                        [proxy_chunk],
                        shape=(np.nan, np.nan),
                        index=reduce_idx,
                        **chunk_kw,
                    )
                )
        out_chunks.sort(key=lambda c: c.index)
    else:
        # all axes need shuffle
        assert splits.no_axis_can_split()

        # gen map chunks
        map_chunks = []
        for chunk in df.chunks:
            map_op = DataFrameIndexAlignMap(
                sparse=chunk.issparse(),
                index_shuffle_size=out_shape[0],
                column_shuffle_size=out_shape[1],
                object_type=ObjectType.dataframe,
            )
            map_chunks.append(
                map_op.new_chunk([chunk], shape=(np.nan, np.nan), index=chunk.index)
            )

        proxy_chunk = DataFrameShuffleProxy(object_type=ObjectType.dataframe).new_chunk(
            map_chunks, shape=()
        )

        # gen reduce chunks
        for out_idx in itertools.product(*(range(s) for s in out_shape)):
            reduce_op = DataFrameIndexAlignReduce(
                i=out_idx,
                sparse=proxy_chunk.issparse(),
                shuffle_key=",".join(str(idx) for idx in out_idx),
                object_type=ObjectType.dataframe,
            )
            out_chunks.append(
                reduce_op.new_chunk(
                    [proxy_chunk], shape=(np.nan, np.nan), index=out_idx
                )
            )

    return out_chunks


# Traceback (Exception)
In [28]: df = md.DataFrame(np.random.rand(10, 2))

In [29]: df + np.random.rand(10, 2)
---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)
<ipython-input-29-4a212df011a8> in <module>
----> 1 df + np.random.rand(10, 2)

~/Documents/mars_dev/mars/mars/dataframe/utils.py in wrapper(*args, **kwargs)
613     def wrapper(*args, **kwargs):
614         try:
--> 615             return func(*args, **kwargs)
616         except NotImplementedError:
617             return NotImplemented

~/Documents/mars_dev/mars/mars/dataframe/arithmetic/add.py in add(df, other, axis, level, fill_value)
33
34 def add(df, other, axis='columns', level=None, fill_value=None):
---> 35     other = wrap_sequence(other)
36     op = DataFrameAdd(axis=axis, level=level, fill_value=fill_value, lhs=df, rhs=other)
37     return op(df, other)

~/Documents/mars_dev/mars/mars/dataframe/utils.py in wrap_sequence(seq)
606
607     if isinstance(seq, (list, tuple, np.ndarray, TENSOR_TYPE)):
--> 608         seq = Series(seq)
609     return seq
610

~/Documents/mars_dev/mars/mars/dataframe/initializer.py in __init__(self, data, index, dtype, name, copy, chunk_size, gpu, sparse)
46             series = data
47         else:
---> 48             pd_series = pd.Series(data, index=index, dtype=dtype, name=name, copy=copy)
49             series = from_pandas_series(pd_series, chunk_size=chunk_size, gpu=gpu, sparse=sparse)
50         super(Series, self).__init__(series.data)

~/miniconda3/lib/python3.7/site-packages/pandas/core/series.py in __init__(self, data, index, dtype, name, copy, fastpath)
312                     data = data.copy()
313             else:
--> 314                 data = sanitize_array(data, index, dtype, copy, raise_cast_failure=True)
315
316                 data = SingleBlockManager(data, index, fastpath=True)

~/miniconda3/lib/python3.7/site-packages/pandas/core/internals/construction.py in sanitize_array(data, index, dtype, copy, raise_cast_failure)
727     elif subarr.ndim > 1:
728         if isinstance(data, np.ndarray):
--> 729             raise Exception("Data must be 1-dimensional")
730         else:
731             subarr = com.asarray_tuplesafe(data, dtype=dtype)

Exception: Data must be 1-dimensional

# Fixed code
def _gen_dataframe_chunks(splits, out_shape, left_or_right, df):
    out_chunks = []
    if splits.all_axes_can_split():
        # no shuffle for all axes
        kw = {
            "index_shuffle_size": -1 if splits[0].isdummy() else None,
            "column_shuffle_size": -1 if splits[1].isdummy() else None,
        }
        for out_idx in itertools.product(*(range(s) for s in out_shape)):
            row_idx = splits.get_axis_idx(0, left_or_right, out_idx[0])
            col_idx = splits.get_axis_idx(1, left_or_right, out_idx[1])
            index_min_max = splits.get_axis_split(0, left_or_right, out_idx[0])
            column_min_max = splits.get_axis_split(1, left_or_right, out_idx[1])
            chunk = df.cix[row_idx, col_idx]
            if _need_align_map(
                chunk,
                index_min_max,
                column_min_max,
                splits[0].isdummy(),
                splits[1].isdummy(),
            ):
                if splits[1].isdummy():
                    dtypes = chunk.dtypes
                else:
                    dtypes = filter_dtypes(chunk.dtypes, column_min_max)
                chunk_kw = {
                    "index_value": chunk.index_value if splits[0].isdummy() else None,
                    "columns_value": chunk.columns_value
                    if splits[1].isdummy()
                    else None,
                }
                align_op = DataFrameIndexAlignMap(
                    index_min_max=index_min_max,
                    column_min_max=column_min_max,
                    dtypes=dtypes,
                    sparse=chunk.issparse(),
                    object_type=ObjectType.dataframe,
                    **kw,
                )
                out_chunk = align_op.new_chunk(
                    [chunk], shape=(np.nan, np.nan), index=out_idx, **chunk_kw
                )
            else:
                out_chunk = chunk
            out_chunks.append(out_chunk)
    elif splits.one_axis_can_split():
        # one axis needs shuffle
        shuffle_axis = 0 if splits[0] is None else 1
        align_axis = 1 - shuffle_axis

        for align_axis_idx in range(out_shape[align_axis]):
            if align_axis == 0:
                kw = {
                    "index_min_max": splits.get_axis_split(
                        align_axis, left_or_right, align_axis_idx
                    ),
                    "index_shuffle_size": -1 if splits[0].isdummy() else None,
                    "column_shuffle_size": out_shape[shuffle_axis],
                }
                input_idx = splits.get_axis_idx(
                    align_axis, left_or_right, align_axis_idx
                )
            else:
                kw = {
                    "column_min_max": splits.get_axis_split(
                        align_axis, left_or_right, align_axis_idx
                    ),
                    "index_shuffle_size": out_shape[shuffle_axis],
                    "column_shuffle_size": -1 if splits[1].isdummy() else None,
                }
                input_idx = splits.get_axis_idx(
                    align_axis, left_or_right, align_axis_idx
                )
            input_chunks = [c for c in df.chunks if c.index[align_axis] == input_idx]
            map_chunks = []
            for j, input_chunk in enumerate(input_chunks):
                chunk_kw = dict()
                if align_axis == 0:
                    chunk_kw["index_value"] = (
                        input_chunk.index_value if splits[0].isdummy() else None
                    )
                else:
                    chunk_kw["columns_value"] = (
                        input_chunk.columns_value if splits[1].isdummy() else None
                    )
                map_op = DataFrameIndexAlignMap(
                    sparse=input_chunk.issparse(),
                    object_type=ObjectType.dataframe,
                    **kw,
                )
                idx = [None, None]
                idx[align_axis] = align_axis_idx
                idx[shuffle_axis] = j
                map_chunks.append(
                    map_op.new_chunk(
                        [input_chunk],
                        shape=(np.nan, np.nan),
                        index=tuple(idx),
                        **chunk_kw,
                    )
                )
            proxy_chunk = DataFrameShuffleProxy(
                sparse=df.issparse(), object_type=ObjectType.dataframe
            ).new_chunk(map_chunks, shape=())
            for j in range(out_shape[shuffle_axis]):
                chunk_kw = dict()
                if align_axis == 0:
                    chunk_kw["index_value"] = (
                        proxy_chunk.inputs[0].inputs[0].index_value
                        if splits[0].isdummy()
                        else None
                    )
                else:
                    chunk_kw["columns_value"] = (
                        proxy_chunk.inputs[0].inputs[0].columns_value
                        if splits[1].isdummy()
                        else None
                    )
                reduce_idx = (
                    (align_axis_idx, j) if align_axis == 0 else (j, align_axis_idx)
                )
                reduce_op = DataFrameIndexAlignReduce(
                    i=j,
                    sparse=proxy_chunk.issparse(),
                    shuffle_key=",".join(str(idx) for idx in reduce_idx),
                    object_type=ObjectType.dataframe,
                )
                out_chunks.append(
                    reduce_op.new_chunk(
                        [proxy_chunk],
                        shape=(np.nan, np.nan),
                        index=reduce_idx,
                        **chunk_kw,
                    )
                )
        out_chunks.sort(key=lambda c: c.index)
    else:
        # all axes need shuffle
        assert splits.no_axis_can_split()

        # gen map chunks
        map_chunks = []
        for chunk in df.chunks:
            map_op = DataFrameIndexAlignMap(
                sparse=chunk.issparse(),
                index_shuffle_size=out_shape[0],
                column_shuffle_size=out_shape[1],
                object_type=ObjectType.dataframe,
            )
            map_chunks.append(
                map_op.new_chunk([chunk], shape=(np.nan, np.nan), index=chunk.index)
            )

        proxy_chunk = DataFrameShuffleProxy(object_type=ObjectType.dataframe).new_chunk(
            map_chunks, shape=()
        )

        # gen reduce chunks
        for out_idx in itertools.product(*(range(s) for s in out_shape)):
            reduce_op = DataFrameIndexAlignReduce(
                i=out_idx,
                sparse=proxy_chunk.issparse(),
                shuffle_key=",".join(str(idx) for idx in out_idx),
                object_type=ObjectType.dataframe,
            )
            out_chunks.append(
                reduce_op.new_chunk(
                    [proxy_chunk], shape=(np.nan, np.nan), index=out_idx
                )
            )

    return out_chunks