angu
@angu

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

'Index' object has no attribute 'strftime'というエラーが表示されます

'Index' object has no attribute 'strftime'というエラーが表示されます

スクリーンショット 2022-09-23 16.43.21.png
スクリーンショット 2022-09-23 16.43.27.png

pythonで株価可視化アプリをつくっています。

解決方法を教えて下さい。

自分で試したこと

strftimeは二枚目で定義しています。
何度も試しましたが図のようなエラーが表示されます

0

2Answer

コード全文を載せていただいたおかげでエラーの原因がよくわかりました.
返信欄に記述するのではなくて,質問自体を編集していただいて上の方にコードブロックを使って掲載していただけるとありがたいです.コードブロック例を示しておきますので参考にしてください.

(空行)
```python
コード本文
```

解決法

普通,何かしらの異常があった場合その前後で扱う変数などのパラメータを出力させて確認するのが常套手段です.

他のhistに対してhist.index.strftime()を実行できるにも関わらず,今回のデータに対して実行できなかったのであれば何かしらの異常があるとみてデバッグを試みる必要があります.

次のようにコードを書いてみて検証しました.

import yfinance as yf

days = 20
hist = yf.Ticker('FB').history(period = f"{days}d")
print(hist.index) # hist.indexに異常がないか確認する.
hist.index = hist.index.strftime("%d %B %Y") # ここでエラーが起きている

すると,

- FB: No data found, symbol may be delisted
Index([], dtype='object', name='Date')
Traceback (most recent call last):
  File "main.py", line 11, in <module>
    hist.index = hist.index.strftime("%d %B %Y")
AttributeError: 'Index' object has no attribute 'strftime'

このような出力が得られました.最初の1,2行はhist.indexに対して得られた出力で, なんなら質問の画像1枚目にも書かれている内容です. 翻訳にかけてみると

翻訳前: - FB: No data found, symbol may be delisted
翻訳後: - FB: データが見つからず、上場廃止の可能性あり

となりました.FaceBookが上場廃止な訳ありません.近年,名前がMETAに変わったことを思い出してMETAに置換して実行したところ,

    days = 20
-   hist = yf.Ticker('FB').history(period = f"{days}d")
+   hist = yf.Ticker('META').history(period = f"{days}d")
    print(hist.index)
    hist.index = hist.index.strftime("%d %B %Y")

以下のように望んだであろう情報が得られていることがわかります.そしてエラーは消えました.

DatetimeIndex(['2022-08-26', '2022-08-29', '2022-08-30', '2022-08-31',
               '2022-09-01', '2022-09-02', '2022-09-06', '2022-09-07',
               '2022-09-08', '2022-09-09', '2022-09-12', '2022-09-13',
               '2022-09-14', '2022-09-15', '2022-09-16', '2022-09-19',
               '2022-09-20', '2022-09-21', '2022-09-22', '2022-09-23'],
              dtype='datetime64[ns]', name='Date', freq=None)

「自分で試したこと」の欄で「何度も試した」とは言っていますが,何度も試して結果が良くなるケース1は限られており,大体の場合不適な手段です.

上でやったように,適切にデータを確認して処理の流れに対して調査を行うのが大事です.

結論

以下の変更をおこなってください.

tickers = {
    'apple': 'AAPL',
-   'facebook': 'FB'
+   'facebook': 'META'
}
  1. ハードウェアの状態に依存するコードか,環境状態に依存するコード,もしくは乱数seedを時間で変更しているコードなどが挙げられます.今回はWeb上のデータに依存していますが,株とはいえそんなに頻繁に変わるデータでもありません.秒単位で実行の可否が変わっては信用に関わります.

4Like

Comments

  1. @angu

    Questioner


    @PondVillege様
    わかりやすい解説、ありがとうございます!おかげさまで無事解決することができました!
    間違ったコードを入れたままにもかかわらず『何度も試した』は我ながらに愚行でした汗

    今後はデバックを確認しつつ、データを確認して処理の流れに対して適切に調査せるよう心がけます。また@PondVillege様のような熟練エンジニアに一日でも早くなれるよう努力いたします!

Comments

  1. @angu

    Questioner

    かしこまりました、ちなみにjupyternotebookで出力させています。

    !pip3 install yfinance

    import pandas as pd
    import matplotlib.pyplot as plt
    import yfinance as yf

    %matplotlib inline

    aapl = yf.Ticker('AAPL')

    days = 20
    hist = aapl.history(period=f'{days}d')
    hist

    hist.reset_index()

    hist_msft = yf.Ticker('MSFT').history(period=f'{days}d')
    hist_msft.head()

    pd.concat([hist, hist_msft], axis=1).head()

    hist.head(3)

    hist.index

    hist.index = hist.index.strftime('%d %B %Y')

    hist = hist[['Close']]
    hist.columns = ['aaple']
    hist.head()

    hist = hist.T
    hist

    hist.index.name = 'Name'

    hist

    def get_data(days, tickers):
    df = pd.DataFrame()
    for company in tickers.keys():
    # company = 'facebook'
    tkr = yf.Ticker(tickers[company])
    hist = tkr.history(period=f'{days}d')
    hist.index = hist.index.strftime('%d %B %Y')
    hist = hist[['Close']]
    hist.columns = [company]
    hist = hist.T
    hist.index.name = 'Name'
    df = pd.concat([df, hist])
    return df

    days = 20
    tickers = {
    'apple': 'AAPL',
    'facebook': 'FB',
    'google': 'GOOGL',
    'microsoft': 'MSFT',
    'netflix': 'NFLX',
    'amazon': 'AMZN'
    }

    get_data(days, tickers)

Your answer might help someone💌