如何从yfinance返回的标普500指数数据中提取日期与收盘价并插入MySQL数据库
如何从yfinance返回的标普500指数数据中提取日期与收盘价并插入MySQL数据库
嗨,你遇到的问题其实很典型——yfinance返回的DataFrame里,日期并不是一个普通的列,而是数据的索引(Index),所以你直接用["Date"]去访问自然会报KeyError。我来帮你调整代码,顺利提取数据并插入MySQL。
问题根源分析
看你打印的spxHistoricalData结果,Date那一行是左对齐单独显示的,这就说明它是这个DataFrame的索引,而不是和Close、High并列的列。所以你不能用列名的方式去获取它,得从索引里提取。
修正后的完整代码
我把你的代码做了两处关键修改,同时保留了批量插入的逻辑:
import yfinance as yf import mysql.connector import pandas as pd # 下载标普500数据 spxHistoricalData = yf.download("^GSPC", start="2000-01-01", end="2025-01-01") # 方式1:直接从迭代的index中获取日期(推荐,不用修改原数据结构) # 生成待插入的日期和收盘价列表 values = [(index, row["Close"]) for index, row in spxHistoricalData.iterrows()] # --------------------------- 如果你更喜欢把日期转成列,用下面这段替代上面的values生成 --------------------------- # spxHistoricalData.reset_index(inplace=True) # 将索引转为名为"Date"的列 # values = [(row["Date"], row["Close"]) for index, row in spxHistoricalData.iterrows()] # -------------------------------------------------------------------------------------------------------- print("待插入的数据示例:", values[:5]) # 打印前5条验证 # 连接MySQL并批量插入 connection = mysql.connector.connect( host="127.0.0.1", port=3306, user="root", password="password", database="bitcoin_and_sp500_price_prediction" ) cursor = connection.cursor() try: sql_query = "INSERT INTO spx_historical_data (date, close_price) VALUES (%s, %s)" cursor.executemany(sql_query, values) connection.commit() print(f"成功插入{cursor.rowcount}条数据!") except mysql.connector.Error as err: print(f"错误发生:{err}") connection.rollback() # 出错时回滚操作,避免数据不一致 finally: cursor.close() connection.close()
关键修改点说明
日期的提取方式:
- 推荐用
iterrows()返回的index作为日期,因为这样不需要修改原DataFrame的结构,更高效。 - 如果习惯用列名访问,可以调用
reset_index(inplace=True)把索引转为名为Date的列,之后就能像你原来想的那样用row["Date"]获取了。
- 推荐用
错误处理优化:
我加了connection.rollback(),如果插入过程中出错,会回滚到操作前的状态,避免数据库出现半插入的异常数据。数据验证:
加了print("待插入的数据示例:", values[:5]),可以提前确认日期和收盘价的格式是否正确,方便排查问题。
关于你之前的报错
你原来写的print(spxHistoricalData[["Date", "Close"]])会报错,因为Date不是列。如果用了reset_index()之后,这行代码就能正常运行了;如果不改结构,想查看日期和收盘价可以这样写:
print(pd.DataFrame({"Date": spxHistoricalData.index, "Close": spxHistoricalData["Close"]}))
这样调整后,你的代码应该就能顺利把数据插入MySQL啦!
备注:内容来源于stack exchange,提问作者Onyx
相关产品推荐
相关产品推荐

