# Buggy code
def tile(cls, op):
    out = op.outputs[0]
    target = op.target
    value = op.value
    col = op.indexes
    columns = target.columns_value.to_pandas()

    if not np.isscalar(value):
        # check if all chunk's index_value are identical
        target_chunk_index_values = [
            c.index_value for c in target.chunks if c.index[1] == 0
        ]
        value_chunk_index_values = [v.index_value for v in value.chunks]
        is_identical = len(target_chunk_index_values) == len(
            target_chunk_index_values
        ) and all(
            c.key == v.key
            for c, v in zip(target_chunk_index_values, value_chunk_index_values)
        )
        if not is_identical:
            # do rechunk
            if any(np.isnan(s) for s in target.nsplits[0]) or any(
                np.isnan(s) for s in value.nsplits[0]
            ):  # pragma: no cover
                raise TilesError("target or value has unknown chunk shape")

            value = value.rechunk({0: target.nsplits[0]})._inplace_tile()

    out_chunks = []
    nsplits = [list(ns) for ns in target.nsplits]
    if col not in columns:
        nsplits[1][-1] += 1
        column_chunk_shape = target.chunk_shape[1]
        # append to the last chunk on columns axis direction
        for c in target.chunks:
            if c.index[-1] != column_chunk_shape - 1:
                # not effected, just output
                out_chunks.append(c)
            else:
                chunk_op = op.copy().reset_key()
                if np.isscalar(value):
                    chunk_inputs = [c]
                else:
                    value_chunk = value.cix[c.index[0],]
                    chunk_inputs = [c, value_chunk]

                dtypes = c.dtypes.copy(deep=True)
                dtypes.loc[out.dtypes.index[-1]] = out.dtypes.iloc[-1]
                chunk = chunk_op.new_chunk(
                    chunk_inputs,
                    shape=(c.shape[0], c.shape[1] + 1),
                    dtypes=dtypes,
                    index_value=c.index_value,
                    columns_value=parse_index(dtypes.index, store_data=True),
                    index=c.index,
                )
                out_chunks.append(chunk)
    else:
        # replace exist column
        for c in target.chunks:
            if col in c.dtypes:
                chunk_inputs = [c]
                if not np.isscalar(value):
                    chunk_inputs.append(value.cix[c.index[0],])
                chunk_op = op.copy().reset_key()
                chunk = chunk_op.new_chunk(
                    chunk_inputs,
                    shape=c.shape,
                    dtypes=c.dtypes,
                    index_value=c.index_value,
                    columns_value=c.columns_value,
                    index=c.index,
                )
                out_chunks.append(chunk)
            else:
                out_chunks.append(c)

    params = out.params
    params["nsplits"] = tuple(tuple(ns) for ns in nsplits)
    params["chunks"] = out_chunks
    new_op = op.copy()
    return new_op.new_tileables(op.inputs, kws=[params])


# Traceback (TypeError)
In [1]: import mars.dataframe as md

In [2]: import mars.tensor as mt

In [3]: df = md.DataFrame(mt.random.rand(10 ,3))

In [4]: df['a'] = df[0].mean()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-fdfc58da199a> in <module>
----> 1 df['a'] = df[0].mean()

~/Workspace/mars/mars/dataframe/indexing/setitem.py in dataframe_setitem(df, col, value)
172 def dataframe_setitem(df, col, value):
173     op = DataFrameSetitem(target=df, indexes=col, value=value)
--> 174     return op(df, value)

~/Workspace/mars/mars/utils.py in _inner(*args, **kwargs)
449         def _inner(*args, **kwargs):
450             with self:
--> 451                 return func(*args, **kwargs)
452
453         return _inner

~/Workspace/mars/mars/dataframe/indexing/setitem.py in __call__(self, target, value)
69                 value_dtype = value.dtype
70             elif is_list_like(value) or isinstance(value, TENSOR_TYPE):
---> 71                 value = asseries(value, index=target.index)
72                 inputs.append(value)
73                 value_dtype = value.dtype

~/Workspace/mars/mars/dataframe/initializer.py in __init__(self, data, index, dtype, name, copy, chunk_size, gpu, sparse)
66             if chunk_size is not None:
67                 data = data.rechunk(chunk_size)
---> 68             series = series_from_tensor(data, index=index, name=name, gpu=gpu, sparse=sparse)
69         elif isinstance(index, INDEX_TYPE):
70             series = series_from_tensor(astensor(data, chunk_size=chunk_size), index=index,

~/Workspace/mars/mars/dataframe/datasource/from_tensor.py in series_from_tensor(tensor, index, name, gpu, sparse)
467 def series_from_tensor(tensor, index=None, name=None, gpu=None, sparse=False):
468     if tensor.ndim > 1 or tensor.ndim <= 0:
--> 469         raise TypeError(f'Not support create DataFrame from {tensor.ndim} dims tensor')
470     gpu = tensor.op.gpu if gpu is None else gpu
471     op = SeriesFromTensor(dtype=tensor.dtype, gpu=gpu, sparse=sparse)

TypeError: Not support create DataFrame from 0 dims tensor

# Fixed code
def tile(cls, op):
    out = op.outputs[0]
    target = op.target
    value = op.value
    col = op.indexes
    columns = target.columns_value.to_pandas()
    is_value_scalar = np.isscalar(value) or cls._is_scalar_tensor(value)

    if not is_value_scalar:
        # check if all chunk's index_value are identical
        target_chunk_index_values = [
            c.index_value for c in target.chunks if c.index[1] == 0
        ]
        value_chunk_index_values = [v.index_value for v in value.chunks]
        is_identical = len(target_chunk_index_values) == len(
            target_chunk_index_values
        ) and all(
            c.key == v.key
            for c, v in zip(target_chunk_index_values, value_chunk_index_values)
        )
        if not is_identical:
            # do rechunk
            if any(np.isnan(s) for s in target.nsplits[0]) or any(
                np.isnan(s) for s in value.nsplits[0]
            ):  # pragma: no cover
                raise TilesError("target or value has unknown chunk shape")

            value = value.rechunk({0: target.nsplits[0]})._inplace_tile()

    out_chunks = []
    nsplits = [list(ns) for ns in target.nsplits]
    if col not in columns:
        nsplits[1][-1] += 1
        column_chunk_shape = target.chunk_shape[1]
        # append to the last chunk on columns axis direction
        for c in target.chunks:
            if c.index[-1] != column_chunk_shape - 1:
                # not effected, just output
                out_chunks.append(c)
            else:
                chunk_op = op.copy().reset_key()
                if pd.api.types.is_scalar(value):
                    chunk_inputs = [c]
                elif is_value_scalar:
                    chunk_inputs = [c, value.chunks[0]]
                else:
                    value_chunk = value.cix[c.index[0],]
                    chunk_inputs = [c, value_chunk]

                dtypes = c.dtypes.copy(deep=True)
                dtypes.loc[out.dtypes.index[-1]] = out.dtypes.iloc[-1]
                chunk = chunk_op.new_chunk(
                    chunk_inputs,
                    shape=(c.shape[0], c.shape[1] + 1),
                    dtypes=dtypes,
                    index_value=c.index_value,
                    columns_value=parse_index(dtypes.index, store_data=True),
                    index=c.index,
                )
                out_chunks.append(chunk)
    else:
        # replace exist column
        for c in target.chunks:
            if col in c.dtypes:
                chunk_inputs = [c]
                if not np.isscalar(value):
                    chunk_inputs.append(value.cix[c.index[0],])
                chunk_op = op.copy().reset_key()
                chunk = chunk_op.new_chunk(
                    chunk_inputs,
                    shape=c.shape,
                    dtypes=c.dtypes,
                    index_value=c.index_value,
                    columns_value=c.columns_value,
                    index=c.index,
                )
                out_chunks.append(chunk)
            else:
                out_chunks.append(c)

    params = out.params
    params["nsplits"] = tuple(tuple(ns) for ns in nsplits)
    params["chunks"] = out_chunks
    new_op = op.copy()
    return new_op.new_tileables(op.inputs, kws=[params])