【问题标题】:Retry Single Iteration in For Loop (Python)在 For 循环中重试单次迭代 (Python)
【发布时间】:2018-11-21 06:51:16
【问题描述】:

这里是 Python 新手(对不起,如果这是一个愚蠢的问题)!我目前正在使用 for 循环来下载和操作数据。不幸的是,我偶尔会遇到导致部分循环失败的简短网络问题。

原来,我在做这样的事情:

# Import Modules
import fix_yahoo_finance as yf
import pandas as pd
from stockstats import StockDataFrame as sdf

# Stock Tickers to Gather Data For - in my full code I have thousands of tickers
Ticker = ['MSFT','SPY','GOOG']

# Data Start and End Data
Data_Start_Date = '2017-03-01'
Data_End_Date = '2017-06-01'

# Create Data List to Append
DataList = pd.DataFrame([])

# Initialize Loop
for i in Ticker:
    # Download Data
    data = yf.download(i, Data_Start_Date, Data_End_Date)
    # Create StockDataFrame
    stock_df = sdf.retype(data)
    # Calculate RSI
    data['rsi'] = stock_df['rsi_14']
    DataList.append(pd.DataFrame(data))

DataList.to_csv('DataList.csv',header=True,index=True)

使用这种基本布局,每当我遇到网络错误时,都会导致整个程序停止并出现错误。

我做了一些研究并尝试将“for循环”修改为以下内容:

for i in Ticker:
  try:
    # Download Data
    data = yf.download(i, Data_Start_Date, Data_End_Date)
    # Create StockDataFrame
    stock_df = sdf.retype(data)
    # Calculate RSI
    data['rsi'] = stock_df['rsi_14']
    DataList.append(pd.DataFrame(data))
  except:
    continue

这样,代码总是可以毫无问题地运行,但每当我遇到网络错误时,它就会跳过它所在的所有代码(无法下载它们的数据)。

我希望它为每个股票下载一次数据。如果失败,我希望它再试一次,直到成功一次,然后继续下一个代码。我尝试使用while True 及其变体,但它导致循环多次下载同一个代码!

非常感谢任何帮助或建议!谢谢!

【问题讨论】:

  • 请在循环尝试时向您展示
  • 斯蒂芬,请accept an answer;它为任何阅读您的问题的人提供了关闭,并且它为回答者提供了一点感激之情。由于您只能接受一个,我建议投票作为一个额外的步骤来表达对多个人的感谢。

标签: python pandas loops for-loop yahoo-api


【解决方案1】:

如果您在遇到故障(某些协议支持)后可以继续,那么最好不要使用这种确切的方法。但是对于稍微蛮力的方法:

for i in Ticker:
  incomplete = True
  tries = 10
  while incomplete and tries > 0:
    try:
      # Download Data
      data = yf.download(i, Data_Start_Date, Data_End_Date)
      incomplete = False
    except:
      tries -= 1
  # Create StockDataFrame
  if incomplete:
    print("Oops, it is really failing a lot, skipping: %r" % (i,))
    continue # not technically needed, but in case you opt to add
             # anything afterward ...
  else:
    stock_df = sdf.retype(data)
    # Calculate RSI
    data['rsi'] = stock_df['rsi_14']
    DataList.append(pd.DataFrame(data))

这与 Prune 略有不同,它会在 10 次尝试后停止……如果多次失败,则表明您可能希望将一些精力转移到解决其他问题上,例如网络连接。

如果达到了这一点,它将继续在Tickers 的列表中,所以也许你可以获得大部分你需要的东西。

【讨论】:

    【解决方案2】:

    您可以使用包装循环继续,直到获得好的结果。

    for i in Ticker:
      fail = True
    
      while fail:     # Keep trying until it works
        try:
          # Download Data
          data = yf.download(i, Data_Start_Date, Data_End_Date)
          # Create StockDataFrame
          stock_df = sdf.retype(data)
          # Calculate RSI
          data['rsi'] = stock_df['rsi_14']
          DataList.append(pd.DataFrame(data))
        except:
          continue
        else:
          fail = False
    

    【讨论】:

    • 什么时候fail 不是False? (我认为你的第一个任务应该是第 2 行中的fail=True。)
    • 不是一个简单的while True + break at the and of the try 块就是这样做的(而不是手动处理fail bool)?
    • 好点,@Julien,尽管跟踪 something 可能是有益的,例如包括失败限制(正如我在回答中所做的那样)。但是,省略单个bool 需要其他形式来确定数据是否完整,而无需显式访问data(除非它之前设置为None 之类的东西)。
    • @both-of-you:好点。我将其编码为通用版本,易于更改以反转逻辑,或为尝试添加计数器。
    • 我最终选择了 r2evans 的方法。它完美地工作!再次感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 2016-08-03
    • 1970-01-01
    • 2018-04-15
    • 1970-01-01
    • 2010-12-02
    • 1970-01-01
    • 2012-06-27
    • 2023-03-05
    相关资源
    最近更新 更多