【问题标题】:Python skip for loop line if exceed time limit and print skipped line如果超过时间限制,Python跳过循环行并打印跳过的行
【发布时间】:2021-06-13 00:24:21
【问题描述】:

类似的问题,但对于这个用例有点不同。我有一个在多个数据帧上运行的函数,我希望在每个数据帧运行时使用一个计时器,如果需要超过 30 秒的时间来跳过它并打印数据帧名称。

功能-

def some_function():
# runs on pd.DataFrames
    cols = [some code]
    rows = [some code]
    df = pd.DataFrame(rows, columns=cols)
    return df

df_1 = some_function()
df_2 = some_function()
df_3 = some_function()

其中df_1 和df_2 各花费不到30 秒,但df_3 花费3 分钟。然后它将运行df_1 和df_2,但打印出df_3 花费了超过30 秒。如何创建这样的定时循环?

编辑

在字典中组织数据帧的循环-

def some_function():
# runs on pd.DataFrames
    cols = [some code]
    rows = [some code]
    t1 = datetime.now()
    if (datetime.now()-t1).seconds <=30:
        df = pd.DataFrame(rows, columns=cols)
    return df

d = {}
dfs = range(0,10)
for name in dfs:
    d[name] = some_function()

我认为这可能会更容易,如果循环并花费太长时间然后跳过?

【问题讨论】:

  • 好吧,如果总时间超过 30 秒,您的新编辑将完全停止处理数据帧。这不是你最初要求的。例如,它不会中断需要很长时间的单个调用。在漫长的通话返回后,它只会放弃。如果没问题,那就去吧。
  • 我很欣赏这个评论,但我是这个结构的新手,并试图获得一些帮助。我的意图是一样的,我只是不知道该怎么做。处理每个数据帧并查看是否需要不到 30 秒,如果是,则处理,如果不是,则打印名称
  • 那么你必须把时间检查放在 some_function 里面。如果处理时间过长,您必须提前退出该功能
  • some_function 里面有多少代码?你能发多少?我知道代码很敏感,但您提供的细节越多,我们的建议就越好。
  • @Tim Roberts 我在第一个块中包含了一些代码片段,基本上是使用游标执行来获取和组织行和列到数据帧中

标签: python function performance for-loop time


【解决方案1】:

基于已编辑的问题。这里的想法是在您完成长时间工作的每个点检查超时条件。

def some_function():
# runs on pd.DataFrames
    t1 = datetime.now()
    cols = [some code]
    if (datetime.now()-t1).seconds > 30:
        return None
    rows = [some code]
    if (datetime.now()-t1).seconds > 30:
        return None
    return pd.DataFrame(rows, columns=cols)

【讨论】:

  • 据我了解,为什么要将if (datetime.now()-t1).seconds &gt;30:return None 分成两部分?
  • 它没有分成两部分。它检查超时两次,第一次是列处理花费了太多时间,第二次是添加行处理花费了太多时间。您可以根据需要多次检查超时。
  • 请注意,检查None 并通过打印消息来诊断它取决于外部代码。
  • 它确实运行了,但它没有为我执行超时检查。是因为代码的第二部分吗? d = {} dfs = range(0,10) for name in dfs: d[name] = some_function()
  • 没有。你不知道它花了多长时间才完成。没有crystal_ball 模块,尽管天知道很多人都尝试过。现在,也许您可​​以计算列和行的长度,并在创建 DataFrame 之前确定有多少是太多...
【解决方案2】:

您必须在 some_function() 中添加代码才能执行此操作。考虑,例如:

def some_function():
    timeout = time.time() + 30
    for some_very_large_loop:
        if time.time() > timeout:
            print( "timeout" )
            return None

如果您有多个处理循环,只需在每个循环中添加该子句。外部代码必须检查 None 并打印诊断信息。

【讨论】:

  • 我对我的帖子进行了一些编辑以更具描述性,我很确定如何按照您在此处的描述应用超时
  • 我可以把df_1、df_2等放在循环中然后这样超时吗?
  • 使用上面的编辑,稍微简化一点,我怎么能加入超时功能
  • 您将超时检查添加到花费最多时间的循环中。这是关键点。您需要采取手动步骤来中断冗长的操作。如果有一个 pandas 操作需要时间,那么你不能停止它。
  • 好的,但是我有一个循环,想检查哪个 df 花费的时间最多
【解决方案3】:

为了停止执行,您需要使用线程。如果您只想表示执行时间过长,您可以编写一个装饰器来自动打印警告消息:

from time import time
def timeLimit(maxTime,name="function"):
    def decorated(f):
        def execute(*arg,**kwarg):
            start    = time()
            result   = f(*arg,**kwarg)
            duration = time()-start
            if duration>maxTime:
                sarg = ",".join(map(str,arg))
                print(f"{name}({sarg}) took more than {maxTime} seconds: {duration}")
            return result
        return execute
    return decorated

用法:

@timeLimit(2,"myfunction") # max 2 seconds
def myfunction(x):
    for _ in range(x*1000000): pass
    return x*x

result = myfunction(30)
result = myfunction(190)

'myfunction(190) took more than 2 seconds: 3.5628979206085205'

【讨论】:

  • 是的,但是,。如果事情花费的时间太长,他有兴趣放弃处理。您的解决方案会诊断出多余的时间,但不会缩短时间。这必须合作完成。
猜你喜欢
  • 1970-01-01
  • 2017-04-07
  • 1970-01-01
  • 1970-01-01
  • 2017-05-09
  • 2021-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多