#python #pandas #apply #yfinance
#python #pandas #применить #yfinance
Вопрос:
У меня есть фрейм данных с тикерами в качестве заголовков и строк с ежедневным скорректированным закрытием за последний год, и я хочу рассчитать годовую волатильность, но я не уверен, как проходить по столбцам. Когда я запускаю этот код, я получаю исключение: TypeError: 'Series' object is not callable
import pandas as pd
import datetime as datetime
from datetime import timedelta
import yfinance as yf
df = pd.read_excel('C:/Users/Jacob/Downloads/Benchmark Tickers.xlsx', sheet_name='Sheet1')
tickers_list = df['Ticker'].tolist()
data = pd.DataFrame(columns=tickers_list)
for ticker in tickers_list:
data[ticker] = yf.download(ticker, start=datetime.datetime.now()-datetime.timedelta(days=365), end=datetime.date.today()) ["Adj Close"]
def volatility(ticker):
return data[ticker].pct_change().rolling(252).std()*(252**0.5)
data[ticker].apply(volatility(ticker))
export_excel = data.to_excel(r'C:/Users/User/Downloads/testvol.xlsx', sheet_name='Sheet1', index= True)
Как бы я применил эту функцию volatility к каждому столбцу?
Вот ссылка на данные, которые извлекаются при выполнении извлечения yfinance: https://docs.google.com/spreadsheets/d/11-kS1ah1lP8v6xv2JQZt_0i7YmynQxIw6q0stEvS_nM/edit?usp=sharing
Ответ №1:
- При использовании
.apply
во фрейме данных сaxis=0
значением по умолчанию вычисления выполняются по столбцам для каждого столбца, поэтому нет необходимости указывать имя каждого тикера.
import pandas as pd
import yfinance as yf
from datetime import datetime, timedelta, date
# given a list of tickers
tickers = ['EFT', 'PPR', 'SRLN']
# create empty dataframe with columns
data = pd.DataFrame(columns=tickers)
# get data
for ticker in tickers:
data[ticker] = yf.download(ticker, start=datetime.now()-timedelta(days=365), end=date.today()) ["Adj Close"]
# perform calculation for each ticker and add it to the calcs dataframe
# 252 is to many for rolling; that means it needs 252 rows to perform the calculation.
# to will be used to show that it's working
calcs = data.apply(lambda x: x.pct_change().rolling(10).std()*(10**0.5))
# display(calcs.head(20))
EFT PPR SRLN
Date
2019-08-20 NaN NaN NaN
2019-08-21 NaN NaN NaN
2019-08-22 NaN NaN NaN
2019-08-23 NaN NaN NaN
2019-08-26 NaN NaN NaN
2019-08-27 NaN NaN NaN
2019-08-28 NaN NaN NaN
2019-08-29 NaN NaN NaN
2019-08-30 NaN NaN NaN
2019-09-03 NaN NaN NaN
2019-09-04 0.009594 0.012125 0.004690
2019-09-05 0.009483 0.012122 0.004691
2019-09-06 0.009870 0.009697 0.004736
2019-09-09 0.009037 0.010020 0.004191
2019-09-10 0.009205 0.009544 0.003981
2019-09-11 0.006672 0.009543 0.004084
2019-09-12 0.006492 0.010054 0.003925
2019-09-13 0.005592 0.010049 0.003992
2019-09-16 0.005428 0.012274 0.003367
2019-09-17 0.004926 0.010776 0.002505
Ответ №2:
Когда вы вызываете apply
ряд, вы не указываете аргумент, как обычно при вызове функции, а передаете его в качестве аргумента ключевого слова:
data[ticker] = data[ticker].apply(volatility, ticker=ticker)
Это должно позаботиться об этом.
В pandas
документации также есть несколько хороших примеров. Смотрите здесь.
Комментарии:
1. Прежде всего, большое спасибо за ваш ответ. Когда я запускаю его таким образом, я получаю ошибку: ValueError: несоответствие формы: массив значений формы (252,) не может быть передан в результат индексации формы (7,0). Не уверен, что это означало, попробовал погуглить. Я все же посмотрю вашу ссылку. Еще раз спасибо за ответ.