将 pandas 系列传递到单列 DataFrame 的装饰器

Decorator to pass pandas Series into one-column DataFrames

我想写一个装饰器,我可以用在为 Pandas DataFrame 编写的函数上,这样当它们接收到实际上是一个系列(甚至可能是一个数组)的输入时,它首先转换出于一般性,输入到单列 Pandas DataFrame 中。这样我就可以使每个函数都适用于 DataFrames 和系列编写函数仅适用于 DataFrames。

类似

@wraps
def does_smt(df, **kwargs):
    for c in df.columns:
        df[c] = do_something(df[c], df.index)
    return df

does_smt(series) # and it also works

我还不太擅长 python 装饰器,但从 Pint 的 ureg.wraps 装饰器来看,我认为这是可以做到的。我检查了那个装饰器,但又一次,因为我在理解装饰器时遇到了麻烦,所以我不知道如何适应它。我还搜索了已经在 Pandas 中定义的装饰器,但似乎有 none.

第一个问题:我该怎么做?

其次:是推荐还是有更好的方法?

干杯

@第一个问题:我该怎么做?

import pandas as pd
from functools import wraps

def seriescapable(func):
    """Decorator for turning the first argument from a pandas.Series to a pandas.DataFrame."""
    @wraps(func)
    def wrapper(*args, **kwargs):
        if args and isinstance(args[0], pd.Series):
            return = func(pd.DataFrame(args[0]), *args[1:], **kwargs)
        return func(*args, **kwargs)
    return wrapper


# Usage example:

@seriescapable
def my_func(df):
    print type(df)
    print df

myfunc(pd.Series([1, 2]))

另见 Python Cookbook: Putting a wrapper around a function

@第二个问题:是推荐,还是有更好的办法?

我认为程序没有根本问题。从语义上讲,它已经足够清楚了,至少在 PEP-318 -- Decorators for Functions and Methods. It adds a bit of processing overhead, but likely that's negligible compared to the calculation you'll perform within the function. For reference, here is also a more general solution for automatic argument conversion.

中使用了类型检查作为示例