# Buggy code
def tile(cls, op):
    inp = op.input
    out = op.outputs[0]

    if len(inp.chunks) == 1:
        chunk_op = op.copy().reset_key()
        chunk_param = out.params
        chunk_param["index"] = (0,)
        chunk = chunk_op.new_chunk(inp.chunks, kws=[chunk_param])

        new_op = op.copy()
        param = out.params
        param["chunks"] = [chunk]
        param["nsplits"] = ((np.nan,),)
        return new_op.new_seriess(op.inputs, kws=[param])

    inp = Series(inp)

    if op.dropna:
        inp = inp.dropna()

    inp = inp.groupby(inp).count(method=op.method)

    if op.normalize:
        if op.convert_index_to_interval:
            check_chunks_unknown_shape([op.input], TilesError)
            inp = inp.truediv(op.input.shape[0], axis=0)
        else:
            inp = inp.truediv(inp.sum(), axis=0)

    if op.sort:
        inp = inp.sort_values(ascending=op.ascending)

    ret = recursive_tile(inp)

    if op.convert_index_to_interval:
        # convert index to IntervalDtype
        chunks = []
        for c in ret.chunks:
            chunk_op = DataFrameValueCounts(
                convert_index_to_interval=True, stage=OperandStage.map
            )
            chunk_params = c.params
            chunk_params["index_value"] = parse_index(
                pd.IntervalIndex([]), c, store_data=False
            )
            chunks.append(chunk_op.new_chunk([c], kws=[chunk_params]))

        new_op = op.copy()
        params = out.params
        params["chunks"] = chunks
        params["nsplits"] = ret.nsplits
        return new_op.new_seriess(out.inputs, kws=[params])

    return [ret]


# Traceback (ValueError)
In [4]: import mars.dataframe as md

In [5]: md.Series(['1-1', '2-2']).map(lambda x: x.split('-')[0]).execute()
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-5-90507c117e4f> in <module>
----> 1 md.Series(['1-1', '2-2']).map(lambda x: x.split('-')[0]).execute()

~/Workspace/mars/mars/dataframe/base/map.py in map_(series, arg, na_action, dtype)
155 def map_(series, arg, na_action=None, dtype=None):
156     op = DataFrameMap(arg=arg, na_action=na_action)
--> 157     return op(series, dtype=dtype)

~/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/base/map.py in __call__(self, series, dtype)
93
94         if dtype is None:
---> 95             raise ValueError('cannot infer dtype, '
96                              'it needs to be specified manually for `map`')
97         else:

ValueError: cannot infer dtype, it needs to be specified manually for `map`

# Fixed code
def tile(cls, op):
    inp = op.input
    out = op.outputs[0]

    if len(inp.chunks) == 1:
        chunk_op = op.copy().reset_key()
        chunk_param = out.params
        chunk_param["index"] = (0,)
        chunk = chunk_op.new_chunk(inp.chunks, kws=[chunk_param])

        new_op = op.copy()
        param = out.params
        param["chunks"] = [chunk]
        param["nsplits"] = ((np.nan,),)
        return new_op.new_seriess(op.inputs, kws=[param])

    inp = Series(inp)

    if op.dropna:
        inp = inp.dropna()

    inp = inp.groupby(inp).count(method=op.method)

    if op.normalize:
        if op.convert_index_to_interval:
            check_chunks_unknown_shape([op.input], TilesError)
            inp = inp.truediv(op.input.shape[0], axis=0)
        else:
            inp = inp.truediv(inp.sum(), axis=0)

    if op.sort:
        inp = inp.sort_values(ascending=op.ascending)

    ret = recursive_tile(inp)

    chunks = []
    for c in ret.chunks:
        chunk_op = DataFrameValueCounts(
            convert_index_to_interval=op.convert_index_to_interval,
            stage=OperandStage.map,
        )
        chunk_params = c.params
        if op.convert_index_to_interval:
            # convert index to IntervalDtype
            chunk_params["index_value"] = parse_index(
                pd.IntervalIndex([]), c, store_data=False
            )
        chunks.append(chunk_op.new_chunk([c], kws=[chunk_params]))

    new_op = op.copy()
    params = out.params
    params["chunks"] = chunks
    params["nsplits"] = ret.nsplits
    return new_op.new_seriess(out.inputs, kws=[params])