社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

Python:nested for循环被字典中的空值中断

Wler • 3 年前 • 1369 次点击  

我对循环和API非常陌生。我目前正在试用IEX的沙箱来收集财务数据。我所做的是收集IEX支持的股票符号列表,然后使用该列表调用数据并将其附加到数据帧中。问题是,有些年IEX没有特定安全性的数据。我希望在数据帧中保持这种安全性,如果缺少值,就写N/A。我的循环代码如下:

my_columns = ['date','Ticker','Price','o_cash_flow','total_income',
          'total_assets','total_liab','rev','ebit','ttm_eps',
          'shares_out','profit_margin','total_rev','2year_return',
          '1year_return','6month_return','3month_return','1month_return']

financials_df = pd.DataFrame(columns = my_columns)

for symbol_string in symbol_strings:
    batch_api_call_url = f'{sandbox_url}/stable/stock/market/batch?symbols={symbol_string}&types=price,financials,stats,advanced-stats&range=2q&token={token}'
    data = requests.get(batch_api_call_url).json()
    for symbol in symbol_string.split(','):
        print(data[symbol])
        financials_df = financials_df.append(
        pd.Series
     [
            data[symbol]['financials']['financials'][0]['fiscalDate'],
            symbol,
            data[symbol]['price'],
            data[symbol]['financials']['financials'][0]['cashFlow'],
            data[symbol]['financials']['financials'][0]['netIncome'],
            data[symbol]['financials']['financials'][0]['totalAssets'],
            data[symbol]['financials']['financials'][0]['totalLiabilities'],
            data[symbol]['financials']['financials'][0]['revenue'],
            data[symbol]['financials']['financials'][0]['ebit'],
            data[symbol]['stats']['ttmEPS'],
            data[symbol]['stats']['sharesOutstanding'],
            data[symbol]['advanced-stats']['profitMargin'],
            data[symbol]['advanced-stats']['totalRevenue'],
            data[symbol]['stats']['year2ChangePercent'],
            data[symbol]['stats']['year1ChangePercent'],
            data[symbol]['stats']['month6ChangePercent'],
            data[symbol]['stats']['month3ChangePercent'],
            data[symbol]['stats']['month1ChangePercent']
    ],
        index = my_columns),
            ignore_index = True
        )

然后,我收到一个错误“KeyError:‘financials’”,这是因为某些证券缺少第二次调用financials。我希望循环只在dataframe中用N/A替换数据,并在发生这种情况时继续从api调用数据。任何帮助都将不胜感激,谢谢。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/129765
 
1369 次点击  
文章 [ 2 ]  |  最新文章 3 年前
Barmar
Reply   •   1 楼
Barmar    3 年前

检查一下 financials 定义为 if 陈述

if 'financials' in data[symbol]['financials']:
    row =  [
        data[symbol]['financials']['financials'][0]['fiscalDate'],
        symbol,
        data[symbol]['price'],
        data[symbol]['financials']['financials'][0]['cashFlow'],
        data[symbol]['financials']['financials'][0]['netIncome'],
        data[symbol]['financials']['financials'][0]['totalAssets'],
        data[symbol]['financials']['financials'][0]['totalLiabilities'],
        data[symbol]['financials']['financials'][0]['revenue'],
        data[symbol]['financials']['financials'][0]['ebit'],
        data[symbol]['stats']['ttmEPS'],
        data[symbol]['stats']['sharesOutstanding'],
        data[symbol]['advanced-stats']['profitMargin'],
        data[symbol]['advanced-stats']['totalRevenue'],
        data[symbol]['stats']['year2ChangePercent'],
        data[symbol]['stats']['year1ChangePercent'],
        data[symbol]['stats']['month6ChangePercent'],
        data[symbol]['stats']['month3ChangePercent'],
        data[symbol]['stats']['month1ChangePercent']
    ]
else:
    row = [
        'N/A',
        symbol,
        data[symbol]['price'],
        'N/A',
        'N/A',
        'N/A',
        'N/A',
        'N/A',
        'N/A',
        data[symbol]['stats']['ttmEPS'],
        data[symbol]['stats']['sharesOutstanding'],
        data[symbol]['advanced-stats']['profitMargin'],
        data[symbol]['advanced-stats']['totalRevenue'],
        data[symbol]['stats']['year2ChangePercent'],
        data[symbol]['stats']['year1ChangePercent'],
        data[symbol]['stats']['month6ChangePercent'],
        data[symbol]['stats']['month3ChangePercent'],
        data[symbol]['stats']['month1ChangePercent']
    ]
financials_df = financials_df.append(pd.Series(row, index=my_columns), ignore_index=True)
jsbueno
Reply   •   2 楼
jsbueno    3 年前

你有这个用途 .get 方法而不是 [...] 检索值的语法。这允许您为缺失案例添加默认值。 但是,由于您是用硬编码的dict查询构建的,因此必须级联 get s用于嵌套字段检索,如果可靠的话,这可能会变得很长。 而且 收到 不检查序列中的元素:尝试从空序列检索索引0处的元素也会出错。

所以 data[symbol]['financials']['financials'][0]['netIncome'] 必须成为

(((d3 if (d3:=d2[0].get("netIncome")) else "N/A")if d2 else "N/A" )if (d2:=d1.get('financials') else "N/A") if (d1:=data[symbol].get('financials')) else "N/A"

可以清楚地看到,即使是像您这样的中等结构,这也不可行。最好的方法是构建一个helper函数,从数据的“路径”中检索嵌套数据,默认为一个值,并每次调用该函数:

def retr(obj, path, default="N/A"):
   try:
      for index in path:
          obj = obj[index]
   except (IndexError, KeyError):
      return default
   return obj

他们会打电话给 retr 要组成每个数据项,请执行以下操作:

data[symbol]['financials']['financials'][0]['cashFlow'],

变成:

retr(data, ["symbol", "financials", "financials", 0 ,"cashFlow"]),