Exemplo n.º 1
0
def transform(obj: FrameOrSeries, func: AggFuncType, axis: Axis, *args,
              **kwargs) -> FrameOrSeries:
    """
    Transform a DataFrame or Series

    Parameters
    ----------
    obj : DataFrame or Series
        Object to compute the transform on.
    func : string, function, list, or dictionary
        Function(s) to compute the transform with.
    axis : {0 or 'index', 1 or 'columns'}
        Axis along which the function is applied:

        * 0 or 'index': apply function to each column.
        * 1 or 'columns': apply function to each row.

    Returns
    -------
    DataFrame or Series
        Result of applying ``func`` along the given axis of the
        Series or DataFrame.

    Raises
    ------
    ValueError
        If the transform function fails or does not transform.
    """
    is_series = obj.ndim == 1

    if obj._get_axis_number(axis) == 1:
        assert not is_series
        return transform(obj.T, func, 0, *args, **kwargs).T

    if isinstance(func, list):
        if is_series:
            func = {com.get_callable_name(v) or v: v for v in func}
        else:
            func = {col: func for col in obj}

    if isinstance(func, dict):
        return transform_dict_like(obj, func, *args, **kwargs)

    # func is either str or callable
    try:
        result = transform_str_or_callable(obj, func, *args, **kwargs)
    except Exception:
        raise ValueError("Transform function failed")

    # Functions that transform may return empty Series/DataFrame
    # when the dtype is not appropriate
    if isinstance(result, (ABCSeries, ABCDataFrame)) and result.empty:
        raise ValueError("Transform function failed")
    if not isinstance(result,
                      (ABCSeries, ABCDataFrame)) or not result.index.equals(
                          obj.index):
        raise ValueError("Function did not transform")

    return result
Exemplo n.º 2
0
def transform(obj: FrameOrSeries, func: AggFuncType, axis: Axis, *args,
              **kwargs) -> FrameOrSeries:
    """
    Transform a DataFrame or Series

    Parameters
    ----------
    obj : DataFrame or Series
        Object to compute the transform on.
    func : string, function, list, or dictionary
        Function(s) to compute the transform with.
    axis : {0 or 'index', 1 or 'columns'}
        Axis along which the function is applied:

        * 0 or 'index': apply function to each column.
        * 1 or 'columns': apply function to each row.

    Returns
    -------
    DataFrame or Series
        Result of applying ``func`` along the given axis of the
        Series or DataFrame.

    Raises
    ------
    ValueError
        If the transform function fails or does not transform.
    """
    from pandas.core.reshape.concat import concat

    is_series = obj.ndim == 1

    if obj._get_axis_number(axis) == 1:
        assert not is_series
        return transform(obj.T, func, 0, *args, **kwargs).T

    if isinstance(func, list):
        if is_series:
            func = {com.get_callable_name(v) or v: v for v in func}
        else:
            func = {col: func for col in obj}

    if isinstance(func, dict):
        if not is_series:
            cols = sorted(set(func.keys()) - set(obj.columns))
            if len(cols) > 0:
                raise SpecificationError(f"Column(s) {cols} do not exist")

        if any(isinstance(v, dict) for v in func.values()):
            # GH 15931 - deprecation of renaming keys
            raise SpecificationError("nested renamer is not supported")

        results = {}
        for name, how in func.items():
            colg = obj._gotitem(name, ndim=1)
            try:
                results[name] = transform(colg, how, 0, *args, **kwargs)
            except Exception as e:
                if str(e) == "Function did not transform":
                    raise e

        # combine results
        if len(results) == 0:
            raise ValueError("Transform function failed")
        return concat(results, axis=1)

    # func is either str or callable
    try:
        if isinstance(func, str):
            result = obj._try_aggregate_string_function(func, *args, **kwargs)
        else:
            f = obj._get_cython_func(func)
            if f and not args and not kwargs:
                result = getattr(obj, f)()
            else:
                try:
                    result = obj.apply(func, args=args, **kwargs)
                except Exception:
                    result = func(obj, *args, **kwargs)
    except Exception:
        raise ValueError("Transform function failed")

    # Functions that transform may return empty Series/DataFrame
    # when the dtype is not appropriate
    if isinstance(result, (ABCSeries, ABCDataFrame)) and result.empty:
        raise ValueError("Transform function failed")
    if not isinstance(result,
                      (ABCSeries, ABCDataFrame)) or not result.index.equals(
                          obj.index):
        raise ValueError("Function did not transform")

    return result