Как добавить столбец в многоуровневый фрейм данных, используя pandas и yfinance? - PullRequest
1 голос
/ 05 августа 2020

У меня есть следующий код:

import yfinance as yf
import pandas as pd
import datetime as dt
end=dt.datetime.today()
start=end-dt.timedelta(59)
tickers=['WBA', 'HD']
ohlcv={}
df=pd.DataFrame
df = yf.download(tickers,group_by=tickers,start=start,end=end,interval='5m')

df['h-l']=abs(df.High-df.Low)
df['h-pc']=abs (df.High-df['Adj Close'].shift(1))
df['l-pc']=abs(df.Low-df['Adj Close'].shift(1))
df['tr']=df[['h-l','h-pc','l-pc']].max(axis=1)
df['atr']=df['tr'].rolling(window=n, min_periods=n).mean()

Когда я пытаюсь запустить его, я получаю указанную ниже ошибку:

return object.__getattribute__(self, name)
AttributeError: 'DataFrame' object has no attribute 'High'

Я пробовал использовать этот код:

df = df.stack(level=0).rename_axis(['Date', 'Ticker']).reset_index(level=1)

извлеченный отчет содержит математические ошибки, так как нет разделения между тикерами.

Когда мне действительно нужно, это для каждого тикера, упомянутого в списке тикеров, он должен создать столбец с именем «hl», где он вычитает максимум этой строки из минимума этой строки и т. д.

1 Ответ

0 голосов
/ 05 августа 2020

Вариант 1: имена многоуровневых столбцов

  • Доступ к многоуровневым столбцам осуществляется путем передачи кортежа
    • df[('WMB', 'High')]
  • Используемые версии пакетов
    • print(pd.__version__) минимум '1.0.5'
    • print(yf.__version__) это '0.1.54'
import yfinance as yf
import pandas as pd
from datetime import datetime, timedelta

end = datetime.today()
start = end - timedelta(59)
tickers = ['WBA', 'HD']

df = yf.download(tickers,group_by=tickers,start=start,end=end,interval='5m')

# iterate over level 0 ticker names
for ticker in tickers:
    df[(ticker, 'h-l')] = abs(df[(ticker, 'High')] - df[(ticker, 'Low')])
    df[(ticker, 'h-pc')] = abs(df[(ticker, 'High')] - df[(ticker, 'Adj Close')].shift(1))
    df[(ticker, 'l-pc')] = abs(df[(ticker, 'Low')] - df[(ticker, 'Adj Close')].shift(1))
    df[(ticker, 'tr')] = df[[(ticker, 'h-l'), (ticker, 'h-pc'), (ticker, 'l-pc')]].max(axis=1)
#     df[(ticker, 'atr')] = df[(ticker, 'tr')].rolling(window=n, min_periods=n).mean()  # not included becasue n is not defined

# sort the columns
df = df.reindex(sorted(df.columns), axis=1)

# display(df.head())
                                   HD                                                                                                          WBA                                                                                              
                            Adj Close       Close        High         Low        Open    Volume       h-l      h-pc      l-pc        tr  Adj Close      Close       High        Low       Open    Volume       h-l      h-pc      l-pc        tr
Datetime                                                                                                                                                                                                                                        
2020-06-08 09:30:00-04:00  253.937500  253.937500  253.960007  252.360001  252.490005  210260.0  1.600006       NaN       NaN  1.600006  46.049999  46.049999  46.070000  45.490002  45.490002  239860.0  0.579998       NaN       NaN  0.579998
2020-06-08 09:35:00-04:00  253.470001  253.470001  254.339996  253.220093  253.990005   95906.0  1.119904  0.402496  0.717407  1.119904  46.330002  46.330002  46.330002  46.040001  46.070000  104259.0  0.290001  0.280003  0.009998  0.290001
2020-06-08 09:40:00-04:00  253.580002  253.580002  253.829895  252.955002  253.429993   55868.0  0.874893  0.359894  0.514999  0.874893  46.610001  46.610001  46.660000  46.240002  46.330002  113174.0  0.419998  0.329998  0.090000  0.419998
2020-06-08 09:45:00-04:00  253.740005  253.740005  253.929993  253.289993  253.529999   61892.0  0.639999  0.349991  0.290009  0.639999  46.880001  46.880001  46.950001  46.624100  46.624100  121388.0  0.325901  0.340000  0.014099  0.340000
2020-06-08 09:50:00-04:00  253.703400  253.703400  253.910004  253.419998  253.740005   60809.0  0.490005  0.169998  0.320007  0.490005  46.919998  46.919998  46.990002  46.820000  46.880001  154239.0  0.170002  0.110001  0.060001  0.170002

Опция 2: Одноуровневые имена столбцов

import yfinance as yf
import pandas as pd
from datetime import datetime, timedelta

tickerStrings = ['WBA', 'HD']
df = yf.download(tickers, group_by='Ticker', start=start ,end=end, interval='5m')

# create single level column names
df = df.stack(level=0).rename_axis(['Date', 'Ticker']).reset_index(level=1)

# function with calculations
def my_calculations(df):
    df['h-l']=abs(df.High-df.Low)
    df['h-pc']=abs(df.High-df['Adj Close'].shift(1))
    df['l-pc']=abs(df.Low-df['Adj Close'].shift(1))
    df['tr']=df[['h-l','h-pc','l-pc']].max(axis=1)
#     df['atr']=df['tr'].rolling(window=n, min_periods=n).mean()  # n is not defined in the question
    return df

# apply the function
df_updated = df.reset_index().groupby('Ticker').apply(my_calculations).sort_values(['Ticker', 'Date'])
...