У меня есть декоратор, который добавляет возврат функции в предоставленный словарь или фрейм данных pandas. Это прекрасно работает, если фрейм данных не имеет другого DateTimeIndex в возвращаемом. Я попытался просто объединить фреймы данных и принять во внимание индекс, но по какой-то причине это означает, что фрейм сбора заканчивается пустым.
Так что этот код работает нормально:
def add_return_to_dict_or_pandas_col_decorator(return_dict):
def actual_decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
nonlocal return_dict
return_dict[args[0]] = func(*args, **kwargs)
return wrapper
return actual_decorator
Применительно к:
accumulate_dict = dict()
@add_return_to_dict_or_pandas_col_decorator(accumulate_dict)
def f2(identifier, x):
return x * x
f2('thrity', 30)
f2('three', 3)
print(accumulate_dict)
accumulate_df = pd.DataFrame()
@add_return_to_dict_or_pandas_col_decorator(accumulate_df)
def f3(identifier, x):
return [x, x * x, x + x]
f3('thrity', 30)
f3('three', 3)
print(accumulate_df)
Но использование функций, возвращающих фреймы данных с DateTimeIndex, приводит к сбою (потому что они на самом деле не совпадают). Вот попытка исправить это:
def add_return_to_pandas_indexed_col_decorator(return_data_frame):
def actual_decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
nonlocal return_data_frame
if return_data_frame.shape[0] > 0:
return_data_frame = pd.merge(return_data_frame, func(*args, **kwargs),
how='outer', left_index=True, right_index=True)
else:
return_data_frame = func(*args, **kwargs)
return wrapper
return actual_decorator
Теперь мой тестовый код фактически проходит через это (просто представьте, что функция возвращает фрейм данных с DateTimeIndex), но конечным результатом является пустой фрейм данных.
return_df = pd.DataFrame()
tckrs = ['GLD', 'GDX']
@add_return_to_pandas_indexed_col_decorator(return_df)
def set_df_get_return_series(*args, **kwargs):
return get_return_series(*args, **kwargs)
for ticker in tckrs:
set_df_get_return_series(ticker)
print(return_df)
Где get_return_series
:
def get_return_series(ticker):
from faker import Faker
fake = Faker()
return pd.DataFrame(np.random.randn(2).tolist(),
columns=[ticker],
index=pd.DatetimeIndex([fake.date_between(start_date='-30y', end_date='-1d'),
fake.date_between(start_date='today', end_date='+30y')]))