如何用yfinance获取多公司行情合并为总DataFrame导入Postgres
解决方案
问题根因
你原代码未达预期的核心原因是:循环遍历ticker列表时,每次都直接覆盖df变量,最终df仅保留了最后一个ticker的行情数据,没有把所有标的的结果汇总。
优化后可直接运行的代码
import pandas as pd import yfinance as yf # 灵活增删ticker仅需修改这个列表即可 tickers = ['VIR','PATH'] # 初始化空列表存储单只股票的DataFrame df_list = [] for ticker in tickers: # 单只拉取,某只拉取失败不影响其他标的 df_yahoo = yf.download(ticker, # start='2000-01-01', # end='2010-12-31', progress=True) # 过滤空数据,避免拉取失败的标的产生空df影响最终结果 if not df_yahoo.empty: df_yahoo.insert(0, 'TICKER', ticker) df_list.append(df_yahoo) # 合并所有标的的数据为统一主DataFrame main_df = pd.concat(df_list, axis=0) # 导出为csv file_name = "/Users/kevin/Dropbox/Programming/Python/test_data/deleteme.csv" main_df.to_csv(file_name) print(main_df)
如果你追求更高的拉取效率,也可以直接给yfinance传ticker列表批量拉取,无需循环:
# 批量拉取写法 tickers = ['VIR','PATH'] df_yahoo = yf.download(tickers, progress=True) # 转换为和上面一样的长表结构 main_df = df_yahoo.stack(level=1).rename_axis(['Date', 'TICKER']).reset_index(level=1)
适配核心需求的优化建议
- 导入Postgres:可以不用走csv导出+COPY的流程,用
sqlalchemy库的to_sql方法直接把主DataFrame写入Postgres,步骤更简洁。如果要保留原流程,当前生成的主df导出的csv已经符合COPY的格式要求。 - 便捷更新数据:可以在Postgres里存一张更新记录表,记录每个ticker最后一次拉取的行情日期,下次拉取时把
start参数设为该日期+1天,拉取到的增量数据直接追加到库中即可,无需每次全量重拉。 - 灵活增删ticker:仅需修改代码开头的
tickers列表,新增标的就往列表加代码,移除就删掉对应代码,其他逻辑无需调整。
内容的提问来源于stack exchange,提问作者kevin.c
相关产品推荐
相关产品推荐

