.ipynb代码正常运行但同名.py文件触发IndexError问题求助
问题:Notebook代码可正常运行,转为.py文件后触发IndexError
问题描述
在VS Code中开发Python项目,通过Eikon API获取数据并存入sqlite3数据库。Jupyter Notebook格式的代码能成功将数据上传至数据库,但将相同代码转为.py文件运行时,触发IndexError:访问df.index[0]时索引越界。已尝试调整列名、数据类型等操作,问题仍未解决。
Jupyter Notebook代码
# %% import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns import eikon as ek import json import datetime as dt import sqlite3 as sql # %% ek.set_app_key('45a807bae5a6416c8aaf5be32d64c3be68e5e623') # %% with open('ProductDataJson2.json', 'r') as json_file: data = json.load(json_file) # %% fields_array=['OPEN','HIGH','LOW','CLOSE','VOLUME'] # %% df=pd.DataFrame(columns=['RIC(i)','Category']+fields_array) # %% def geteikondata_daily(ric,fields,start_date,end_date): df=pd.DataFrame() start_date1=start_date end_date1=end_date while True: try: tmp_df=ek.get_timeseries(ric, interval = 'daily', start_date = start_date1, \ end_date = end_date1, fields=fields) df=pd.concat([tmp_df,df]) end_date1=df.index[0]-dt.timedelta(microseconds=1) end_date1=dt.datetime.fromtimestamp(dt.datetime.timestamp(end_date1)) except ek.EikonError as err: print(err) break return df # %% for category, product_list in data.items(): for product in product_list: ric=product['RIC'] fields=['OPEN','HIGH','LOW','CLOSE'] end_date = dt.datetime.utcnow() start_date = end_date - dt.timedelta(days=5) ric_symbols=[f"{ric}c{i}" for i in range(1,2)] for ric_symbol in ric_symbols: retrived_data=geteikondata_daily(ric_symbol,fields,start_date,end_date) if not retrived_data.empty: retrived_data=retrived_data.reindex(columns=fields_array,fill_value=pd.NA) retrived_data=retrived_data.reset_index() retrived_data['RIC(i)']=ric_symbol retrived_data['Category']= category df=pd.concat([df,retrived_data],ignore_index=True) print(df) else: print(f"Data for {ric_symbol} is empty, skipping .....") # %% conn = sql.connect('my_database.db') df.to_sql('my_table', conn, if_exists='replace', index=False)
Python脚本代码
import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns import eikon as ek import json import datetime as dt import sqlite3 as sql with open('ProductDataJson2.json', 'r') as json_file: data = json.load(json_file) fields_array=['OPEN','HIGH','LOW','CLOSE','VOLUME'] df=pd.DataFrame(columns=['RIC(i)','Category']+fields_array) def geteikondata_daily(ric,fields,start_date,end_date): df=pd.DataFrame() start_date1=start_date end_date1=end_date while True: try: tmp_df=ek.get_timeseries(ric, interval = 'daily', start_date = start_date1,end_date = end_date1, fields=fields) df=pd.concat([tmp_df,df]) end_date1=df.index[0]-dt.timedelta(microseconds=1) end_date1=dt.datetime.fromtimestamp(dt.datetime.timestamp(end_date1)) except ek.EikonError as err: print(err) break return df for category, product_list in data.items(): for product in product_list: ric=product['RIC'] fields=['OPEN','HIGH','LOW','CLOSE'] end_date = dt.datetime.utcnow() start_date = end_date - dt.timedelta(days=3) ric_symbols=[f"{ric}c{i}" for i in range(1,3)] for ric_symbol in ric_symbols: retrived_data=geteikondata_daily(ric_symbol,fields,start_date,end_date) if not retrived_data.empty: retrived_data=retrived_data.reindex(columns=fields_array,fill_value=pd.NA) retrived_data=retrived_data.reset_index() retrived_data['RIC(i)']=ric_symbol retrived_data['Category']= category df=pd.concat([df,retrived_data],ignore_index=True) print(df) else: print(f"Data for {ric_symbol} is empty, skipping .....") conn = sql.connect('my_database.db') df.to_sql('my_table', conn, if_exists='replace', index=False)
报错信息
Traceback (most recent call last): File "c:\Users\Project 3 - Market Movement\Back\test.py", line 41, in <module> retrived_data=geteikondata_daily(ric_symbol,fields,start_date,end_date) File "c:\Users\Project 3 - Market Movement\Back\test.py", line 26, in geteikondata_daily end_date1=df.index[0]-dt.timedelta(microseconds=1) File "c:\programdata\anaconda3\lib\site-packages\pandas\core\indexes\base.py", line 5320, in __getitem__ return getitem(key) IndexError: index 0 is out of bounds for axis 0 with size 0
问题原因与解决办法
原因
在geteikondata_daily函数中,当ek.get_timeseries返回空DataFrame时(比如目标RIC无可用数据、API返回为空),pd.concat([tmp_df, df])后的df仍然是空的,此时直接访问df.index[0]就会触发索引越界错误。
Notebook中未触发该错误,是因为测试的RIC范围更小(range(1,2)),没遇到无数据的情况;而.py脚本遍历了更多RIC(range(1,3)),刚好命中了无数据的场景。
解决办法
在访问df.index[0]前,先检查df是否为空,为空则直接跳出循环:
修改后的geteikondata_daily函数:
def geteikondata_daily(ric,fields,start_date,end_date): df=pd.DataFrame() start_date1=start_date end_date1=end_date while True: try: tmp_df=ek.get_timeseries(ric, interval = 'daily', start_date = start_date1,end_date = end_date1, fields=fields) # 当前请求返回空,直接终止循环 if tmp_df.empty: break df=pd.concat([tmp_df,df]) # 确认df非空再访问索引 if df.empty: break end_date1=df.index[0]-dt.timedelta(microseconds=1) end_date1=dt.datetime.fromtimestamp(dt.datetime.timestamp(end_date1)) except ek.EikonError as err: print(err) break return df
内容的提问来源于stack exchange,提问作者NoahVenn
相关产品推荐
相关产品推荐

