Python选股脚本无报错但输出空DataFrame问题求助
股票筛选程序输出空DataFrame问题
运行股票筛选代码后未获取到目标股票列表,输出为空DataFrame,具体输出信息:
runcell(0, 'C:/Users/cades/Downloads/untitled3.py')
Empty DataFrame
Columns: [ticker, earnings_to_equity, debt_to_equity, quick_ratio]
Index: []
使用的原始代码:
import yfinance as yf import pandas as pd tickers = yf.Tickers('') financial_data = pd.DataFrame(columns=['ticker', 'earnings_to_equity', 'debt_to_equity', 'quick_ratio']) for ticker in tickers.tickers: balance_sheet = ticker.balance_sheet income_statement = ticker.income_statement earnings_to_equity = income_statement.loc['Net Income'] / balance_sheet.loc['Total Stockholder Equity'] debt_to_equity = balance_sheet.loc['Total Debt'] / balance_sheet.loc['Total Stockholder Equity'] quick_ratio = (balance_sheet.loc['Total Current Assets'] - balance_sheet.loc['Inventory']) / balance_sheet.loc['Total Current Liabilities'] if debt_to_equity < 2 and quick_ratio >= 1.5 and earnings_to_equity > 0: financial_data = financial_data.append({'ticker': ticker.ticker, 'earnings_to_equity': earnings_to_equity, 'debt_to_equity': debt_to_equity, 'quick_ratio': quick_ratio}, ignore_index=True) if len(financial_data) >= 100: break print(financial_data)
问题原因分析
- 未传入有效股票代码:
yf.Tickers('')参数为空字符串,没有指定任何要筛选的股票,循环根本不会执行,直接输出空DataFrame。 - 财务数据取值有风险:直接用
loc硬取报表字段,不同公司的报表字段命名可能有差异,或yfinance返回结构变动,容易触发KeyError中断程序。 - 多期数据处理错误:yfinance返回的财务报表是包含多期数据的Series,直接相除会得到多期结果的Series,用这个做条件判断逻辑会失效,无法正确筛选。
append方法已弃用:Pandas的append方法早已被标记为弃用,多次调用会导致性能低下。
修复后的代码
import yfinance as yf import pandas as pd # 传入要筛选的股票代码列表,示例用几只主流股票,可替换为批量代码 ticker_list = ['AAPL', 'MSFT', 'GOOG', 'AMZN', 'TSLA'] tickers = yf.Tickers(' '.join(ticker_list)) # 用列表收集数据,替代低效的append financial_records = [] for ticker in tickers.tickers.values(): try: # 获取最新一期的财务数据(取第一列对应最新报告期) balance_sheet = ticker.balance_sheet.iloc[:, 0] income_statement = ticker.income_statement.iloc[:, 0] # 先检查所需字段是否存在,避免KeyError required_balance_cols = ['Total Stockholder Equity', 'Total Debt', 'Total Current Assets', 'Inventory', 'Total Current Liabilities'] if all(col in balance_sheet.index for col in required_balance_cols) and 'Net Income' in income_statement.index: # 计算单期指标(最新一期数据) earnings_to_equity = income_statement['Net Income'] / balance_sheet['Total Stockholder Equity'] debt_to_equity = balance_sheet['Total Debt'] / balance_sheet['Total Stockholder Equity'] quick_ratio = (balance_sheet['Total Current Assets'] - balance_sheet['Inventory']) / balance_sheet['Total Current Liabilities'] # 校验指标为数值类型,避免非数值导致判断错误 if isinstance(debt_to_equity, (int, float)) and isinstance(quick_ratio, (int, float)) and isinstance(earnings_to_equity, (int, float)): if debt_to_equity < 2 and quick_ratio >= 1.5 and earnings_to_equity > 0: financial_records.append({ 'ticker': ticker.ticker, 'earnings_to_equity': round(earnings_to_equity, 2), 'debt_to_equity': round(debt_to_equity, 2), 'quick_ratio': round(quick_ratio, 2) }) # 达到100只股票就停止循环 if len(financial_records) >= 100: break except Exception as e: # 捕获单只股票的异常,不影响整体筛选流程 print(f"处理{ticker.ticker}时出错: {str(e)}") continue # 把收集到的记录转为DataFrame financial_data = pd.DataFrame(financial_records) print(financial_data)
关键修改点说明
- 传入有效股票代码:通过
ticker_list指定要筛选的股票,确保循环能执行。 - 取单期数据:用
iloc[:, 0]获取最新报告期的单条数据,避免多期数据混淆。 - 字段存在性检查:提前判断所需字段是否存在,避免报错中断。
- 列表收集数据:替代
append方法,提升代码性能。 - 异常捕获:处理单只股票的报错,保证整体筛选流程不中断。
- 数值校验:确保指标为数值类型,避免非数值导致的条件判断失效。
内容的提问来源于stack exchange,提问作者Cade172
相关产品推荐
相关产品推荐

