You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

yFinance拉取股票5年历史数据存CSV报错:需传入二维输入

解决yFinance数据保存CSV时的ValueError问题

问题场景

需要拉取多只股票的5年历史数据(如适用)并保存为CSV,后续仅需每日更新本地数据,但测试代码在写入环节报错,错误提示为ValueError: Must pass 2-d input. shape=(1, 561, 7)。原因是将yFinance返回的DataFrame放入列表再转为新DataFrame,导致数据结构异常。

原测试代码:

import yfinance as yf
import pandas as pd

data = pd.DataFrame()
foo = yf.Ticker('GRAB')
temp = pd.DataFrame([foo.history('5y')])

temp.to_csv('out.csv')

报错信息:

Traceback (most recent call last):
File "C:\Users\jmshe\AppData\Local\Programs\Python\Python310\stock 2.py", line 10, in 
temp = pd.DataFrame([foo.history('5y')])
File "C:\Users\jmshe\AppData\Local\Programs\Python\Python310\lib\site-packages\pandas\core\frame.py", line 762, in __init__
mgr = ndarray_to_mgr(
File "C:\Users\jmshe\AppData\Local\Programs\Python\Python310\lib\site-packages\pandas\core\internals\construction.py", line 329, in ndarray_to_mgr
values = _prep_ndarraylike(values, copy=copy_on_sanitize)
File "C:\Users\jmshe\AppData\Local\Programs\Python\Python310\lib\site-packages\pandas\core\internals\construction.py", line 583, in _prep_ndarraylike
raise ValueError(f"Must pass 2-d input. shape={values.shape}")
ValueError: Must pass 2-d input. shape=(1, 561, 7)

解决方案

1. 单只股票数据修正

yf.Ticker.history()本身返回的就是标准2维DataFrame,不需要用列表包裹再转DataFrame,直接使用返回结果即可:

import yfinance as yf
import pandas as pd

foo = yf.Ticker('GRAB')
# 直接获取历史数据DataFrame
temp = foo.history('5y')
# 保存为CSV
temp.to_csv('grab_stock_data.csv')

2. 多只股票数据批量处理

遍历股票代码列表,为每个股票的DataFrame添加股票标识列,再合并成一个大DataFrame保存:

import yfinance as yf
import pandas as pd

# 待拉取的股票代码列表
stock_symbols = ['GRAB', 'AAPL', 'MSFT']
all_data = []

for symbol in stock_symbols:
    ticker = yf.Ticker(symbol)
    df = ticker.history('5y')
    # 添加股票代码列,方便区分不同股票
    df['Symbol'] = symbol
    all_data.append(df)

# 合并所有股票数据
combined_df = pd.concat(all_data)
# 保存为CSV
combined_df.to_csv('multi_stock_data.csv')

3. 每日更新本地数据

读取本地已保存的CSV,获取最新日期,拉取该日期之后的增量数据并追加:

import yfinance as yf
import pandas as pd
from datetime import datetime

csv_path = 'multi_stock_data.csv'
# 读取本地已有数据
existing_df = pd.read_csv(csv_path, index_col=0, parse_dates=True)
# 获取最新日期
latest_date = existing_df.index.max()

# 遍历股票代码,拉取增量数据
stock_symbols = existing_df['Symbol'].unique()
update_data = []

for symbol in stock_symbols:
    ticker = yf.Ticker(symbol)
    # 拉取最新日期之后的数据(注意yfinance的start参数是左闭右开)
    df_update = ticker.history(start=latest_date + pd.Timedelta(days=1))
    if not df_update.empty:
        df_update['Symbol'] = symbol
        update_data.append(df_update)

if update_data:
    # 合并增量数据并追加到本地文件
    update_df = pd.concat(update_data)
    combined_df = pd.concat([existing_df, update_df])
    combined_df.to_csv(csv_path)
    print(f"已更新{len(update_df)}条数据")
else:
    print("当前数据已是最新,无需更新")

内容的提问来源于stack exchange,提问作者James Herndon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 23:16:00