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

Python中使用Yahoo Financials获取股票数据并存储到DataFrame时出现ValueError的问题排查

Alright, let's figure out where you went wrong and fix it step by step!

Why You Got the ValueError

The error happens because you're passing a YahooFinancials class instance directly to the pandas DataFrame constructor. The DataFrame expects structured data like a dictionary, list of dictionaries, or another DataFrame—not an instance of the YahooFinancials class. That's why it throws the "constructor not properly called" error.

Solution: Extract Data First, Then Build Your DataFrame

We need to pull the specific data points you want (PE ratio, price-to-sales, currency, adjusted closing prices) from the YahooFinancials instance, format them into structured data, and then assemble them into usable DataFrames. Here's how to do it:

First, make sure you have the necessary imports:

import pandas as pd
from yahoo_fin import YahooFinancials  # Assuming you're using the yahoo_fin library

Let's assume your assets variable is a list of tickers like ["AAPL", "MSFT", "GOOG"]. We'll reuse a single YahooFinancials instance instead of creating multiple ones (more efficient):

Step 1: Initialize the YahooFinancials Instance

assets = ["AAPL", "MSFT", "GOOG"]
yahoo_financials = YahooFinancials(assets)

Step 2: Build the Fundamental Metrics DataFrame

This will hold your asset names, PE ratio, price-to-sales, and currency:

# Fetch the fundamental data as dictionaries
pe_ratios = yahoo_financials.get_pe_ratio()
price_to_sales = yahoo_financials.get_price_to_sales()
currencies = yahoo_financials.get_currency()

# Convert to a DataFrame
fundamental_df = pd.DataFrame({
    "资产名称": list(pe_ratios.keys()),
    "市盈率(PE ratio)": list(pe_ratios.values()),
    "市销率(Price to Sales)": list(price_to_sales.values()),
    "货币类型": list(currencies.values())
})

print("基本面数据表格:")
print(fundamental_df)

Step 3: Build the Historical Adjusted Closing Prices DataFrame

This will give you a date-indexed table of daily adjusted closes for each asset:

# Fetch historical price data
historical_data = yahoo_financials.get_historical_price_data(
    start_date="2013-01-01",
    end_date="2021-01-30",
    time_interval="daily"
)

# Extract adjusted closes for each asset
price_data = {}
for ticker in assets:
    # Get the list of price entries for the ticker
    ticker_prices = historical_data[ticker]["prices"]
    # Pull out formatted date and adjusted close, then map dates to values
    price_data[ticker] = {entry["formatted_date"]: entry["adjclose"] for entry in ticker_prices}

# Convert to a DataFrame (dates as index, tickers as columns)
price_df = pd.DataFrame(price_data).rename(columns={ticker: f"{ticker}_调整收盘价" for ticker in assets})

print("\n每日调整收盘价表格:")
print(price_df.head())

What This Gives You

  • fundamental_df: A table where each row is an asset with its current PE ratio, price-to-sales ratio, and currency.
  • price_df: A time-series table where each row is a date, and each column is the adjusted closing price for an asset.

If you want to combine these (though note that fundamental metrics are static while prices are daily), you could repeat the fundamental data for each date, but that's usually not necessary for analysis—keeping them separate is cleaner for most use cases.

Key Takeaway

Never pass the raw YahooFinancials instance to pandas. Always extract the specific data you need (which comes as dictionaries or lists from the library's methods) and then structure that data into the format pandas expects.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 06:19:06