#python #pandas
Вопрос:
Меня беспокоит использование groupby.apply
функции в классе. Вот код:
import pandas as pd
import numpy as np
from datetime import datetime, timedelta, date
class Calculator:
def __init__(self):
self.df = pd.DataFrame({'date_time': [date(2021,6,1), date(2021,6,2), date(2021,6,3), date(2021,6,4), date(2021,6,1), date(2021,6,2), date(2021,6,3), date(2021,6,4)],
'ticker': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'B'],
'close': [5, 4, 2, 3, 10, 12, 11, 12]})
def expected_calculation(self):
self.df['weight'] = self.df['close'].values / self.df['close'].sum()
self.df['pct_change'] = self.df['close'].values.pct_change()
def job(self):
self.df = self.df.groupby(['date_time', 'ticker']).apply(self.expected_calculation)
if __name__ == '__main__':
testing = Calculator()
testing.job()
Я попытался запустить приведенный выше код, но он возвращает мне ошибку TypeError: expected_calculation() takes 1 positional argument but 2 were given
. Это необходимо использовать groupby
, потому что я хочу провести расчет по каждому подмножеству (т. Е. по одному набору данных для тикера). Я понимаю, что это связано с apply
функцией, но я не могу найти выход.
Не могли бы вы помочь мне решить эту проблему? Большое спасибо!
Ответ №1:
Это связано с тем,что при использовании apply он передает значения строк в качестве аргументов функции.Поэтому expected_calculation
функция ожидает значения строк в качестве параметра. Другое дело-следовать лучшим практикам при работе с классами.Ваша expeted_calculation
функция не имеет ничего общего с экземплярами class.so его лучше использовать staticmethod
. Попробуйте это решение
class Calculator:
def __init__(self):
self.df = pd.DataFrame({'date_time': [date(2021,6,1), date(2021,6,2), date(2021,6,3), date(2021,6,4), date(2021,6,1), date(2021,6,2), date(2021,6,3), date(2021,6,4)],
'ticker': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'B'],
'close': [5, 4, 2, 3, 10, 12, 11, 12]})
@staticmethod
def expected_calculation(x):
x['weight'] = x['close'].values / x['close'].sum()
x['pct_change'] = x['close'].pct_change()
return x
def job(self):
self.df = self.df.groupby(['date_time', 'ticker']).apply(self.expected_calculation)