将多只股票财务数据转换为Pandas DataFrame时遇属性错误求助
问题:多只股票财报数据转换DataFrame时使用
orient='index'报错 我尝试获取AMZN、AAPL、MSFT、DIS、GOOG多只股票的balance_sheet(资产负债表)、income_statement(利润表)、cash_flow(现金流量表)数据,并转换为DataFrame进行处理。获取数据的代码如下:
import yahoo_fin.stock_info as yfs tickers = ['AMZN','AAPL','MSFT','DIS','GOOG'] balance_sheet=[] income_statement=[] cash_flow=[] balance_sheet.append({ticker : yfs.get_balance_sheet(ticker) for ticker in tickers}) income_statement.append({ticker : yfs.get_income_statement(ticker) for ticker in tickers }) cash_flow.append({ticker : yfs.get_cash_flow(ticker) for ticker in tickers})
此部分可正常运行,每个类别返回一个字典。随后执行以下代码:
my_dict=cash_flow+balance_sheet+income_statement dff=pd.DataFrame.from_dict(my_dict, orient='columns', dtype=None, columns=None)
当尝试使用orient='index'时,出现如下错误:
AttributeError Traceback (most recent call last) in 1 my_dict=cash_flow+balance_sheet+income_statement ----> 2 dff=pd.DataFrame.from_dict(my_dict, orient='index', dtype=None, columns=None) 3 # dff=dff.set_index('endDate') 4 dff 5 # cash_flow /opt/anaconda3/lib/python3.8/site-packages/pandas/core/frame.py in from_dict(cls, data, orient, dtype, columns) 1361 if len(data) > 0: 1362 # TODO speed up Series case -> 1363 if isinstance(list(data.values())[0], (Series, dict)): 1364 data = _from_nested_dict(data) 1365 else: AttributeError: 'list' object has no attribute 'values'
错误原因
pd.DataFrame.from_dict()的orient='index'参数要求输入的data是字典类型,但你这里的my_dict是一个列表(cash_flow、balance_sheet、income_statement都是包含单个字典的列表,相加后变成包含3个字典的列表),列表没有values()方法,因此触发了AttributeError。
另外,你最初的代码里没必要把每个财报字典放进列表:balance_sheet.append({...})会让balance_sheet变成[ {ticker: df, ...} ]这种冗余结构,直接用字典存储即可。
修正方案
步骤1:调整数据存储方式,直接用字典而非列表
把获取数据的代码改成:
import yahoo_fin.stock_info as yfs import pandas as pd tickers = ['AMZN','AAPL','MSFT','DIS','GOOG'] # 直接用字典存储,无需套列表 balance_sheet = {ticker : yfs.get_balance_sheet(ticker) for ticker in tickers} income_statement = {ticker : yfs.get_income_statement(ticker) for ticker in tickers} cash_flow = {ticker : yfs.get_cash_flow(ticker) for ticker in tickers}
步骤2:构造符合orient='index'要求的字典
如果想把三类财报合并成一个大字典供from_dict使用,可以这样做:
# 构造键为财报类型,值为对应股票字典的大字典 full_fin_data = { "cash_flow": cash_flow, "balance_sheet": balance_sheet, "income_statement": income_statement } # 此时用orient='index'可正常生成DataFrame dff = pd.DataFrame.from_dict(full_fin_data, orient='index')
补充:整合所有股票的财报数据到单DataFrame
如果希望把每只股票的三张表数据整合到一个结构化的DataFrame里,可以遍历每个股票,拼接三张表:
result_dfs = [] for ticker in tickers: # 重置索引,统一字段名 bs = balance_sheet[ticker].reset_index().rename(columns={'index': 'item'}) is_ = income_statement[ticker].reset_index().rename(columns={'index': 'item'}) cf = cash_flow[ticker].reset_index().rename(columns={'index': 'item'}) # 合并单只股票的三张表 ticker_df = pd.merge(bs, is_, on=['item', 'endDate'], how='outer') ticker_df = pd.merge(ticker_df, cf, on=['item', 'endDate'], how='outer') ticker_df['ticker'] = ticker result_dfs.append(ticker_df) # 合并所有股票数据 final_df = pd.concat(result_dfs, ignore_index=True)
内容的提问来源于stack exchange,提问作者momo
相关产品推荐
相关产品推荐

