2016-06-20 1 views
0

Я хочу написать декоратор, который я могу использовать для функций, написанных для Pandas DataFrame, так что, когда они получают вход, который на самом деле является серией (или, может быть, даже массивом) он сначала преобразует этот ввод в одностоечный Pandas DataFrame из общности. Таким образом, я могу заставить каждую функцию работать как для DataFrames, так и для функций записи строк только для DataFrames.Декоратор для передачи серии pandas в одностолбцовые 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 

Я не слишком хорошо с питона декораторов пока нет, но судя по ureg.wraps декоратора Pint, я имею в виду, что может быть сделано. Я проверил этот декоратор, но, опять же, поскольку у меня возникли проблемы с пониманием декораторов, я не мог понять, как его адаптировать. Я также искал декоратора, который уже был определен в Пандах, но, похоже, его нет.

Первый вопрос: как я могу это сделать?

Второй: рекомендуется ли это, или есть лучший способ?

Приветствия

ответ

1

@First вопрос: Как я могу это сделать?

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

@Second вопрос: что рекомендуется, или есть способ лучше?

Я не вижу принципиальной проблемы с процедурой. Семантически это достаточно ясно и, по крайней мере, проверка типа используется в качестве примера в PEP-318 -- Decorators for Functions and Methods. Это добавляет немного накладных расходов на обработку, но, вероятно, это незначительно по сравнению с расчетами, которые вы будете выполнять внутри функции. Для справки, здесь также находится more general solution for automatic argument conversion.

+0

спасибо. Это общее решение также довольно аккуратно, хотя я, вероятно, буду использовать ваши. Кроме того, я знаю, что это не было в вопросе (я отредактирую или задаю другой вопрос, если вы захотите), но в случае ввода в серии, есть ли способ переконвертировать вывод в серию в конце ? – TomCho

+0

Не обращай внимания, понял! Эта ссылка, которую вы мне дали, на самом деле действительно хороша, объясняя декораторам. Я не знаю, почему я никогда не пробовал Cookbook python. В любом случае, еще раз спасибо. – TomCho