環境

  • Python 3.7
  • pandas 0.24.2
  • (iOSのアプリ Carnetsで動作)

エラー内容

---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-1-f4a3d43733da> in <module>
---> 47 JPYUSD = df0.iloc[-1]['DEXJPUS']
 48 print('Currency JPY/USD : '+str(JPYUSD))
 49 


IndexError: single positional indexer is out-of-bounds

エラーになった経緯

PandasDataReaderで取得したデータをdf0に格納し、iloc[-1]で’DEXJPUS’列の最終行のデータを取得しようとしたらエラーになった

原因

以下のようにDataFrameが空だったから print(df0)で確認

ilocはDataFrameが空だとダメっぽい

Empty DataFrame

Columns: [DEXJPUS, DEXUSAL, DEXUSNZ, DEXCAUS, JPYAUD, JPYCAD]
Index: []

対策

DataFrameに値を入れておく!(emptyにしない)

実際対策したこと

days=10ではデータが無くてemptyだった様なので、30に増やしたらデータが入った様なので解決した

当該のプログラム

Pandasdatareaderを使ってFREDから為替のデータを取得するプログラムです(現在からn日前のデータ取得)

下のプログラムだとdays=10ですので10日前までのデータを取得しようと動きますが、FREDでの最新データが2020/07/02(2020/07/13時点)なので7/13-7/2=11日前となり10日前までだとデータが取れません。なのでこのままコピペしたら表題のエラーになります。

days=30(1ヶ月前)くらい余裕を持っておけば多分取得できます。(実際やった対策がこれ)

FREDさんが1ヶ月更新してくれなかったらダメですが!

import numpy as np

import pandas as pd
import pandas_datareader.data as pdr
import datetime as dt

# 最新のレートを取得する
end = dt.date.today() # 本日まで
start = end - dt.timedelta(days=10) # 最新のデータが本日付けであるとは限らないので、とりあえず10日前までのデータを取り、その中で最新データを引用する
tickerlist = ['DEXJPUS','DEXUSAL','DEXUSNZ','DEXCAUS'] # 取得するtickerのlist
# DEXJPUS : JPY/USD
# DEXUSAL : USD/AUD
# DEXUSNZ : USD/NZD
# DEXCAUS : CAD/USD

# DataReaderからレートを取得
df0 = pdr.DataReader(tickerlist,'fred',start,end) # 日次データ
df0['JPYAUD'] = df0['DEXJPUS'] * df0['DEXUSAL'] # JPY/AUD算出
df0['JPYCAD'] = df0['DEXJPUS'] * (1 / df0['DEXCAUS']) # JPY/CAD算出

print(df0)

# 最終行のデータを取得(つまり、最新データ)
# ilocで取得すると単一の値になる
# ilocではdataframeがemptyだとエラーになる
JPYUSD = df0.iloc[-1]['DEXJPUS']
print('Currency JPY/USD : '+str(JPYUSD))

おしまい^_^