Python递归尝试除外

时间:2019-05-21 20:04:20

标签: python pandas recursion try-except

我正在尝试创建一个递归try-except函数以处理偶发的错误。在pandas中,我们可以为数据帧创建分位数,但是,可能会发生两个或多个分位数的边界重合,因此实际上没有边界。因此pandas将引发错误。为了避免这种情况,您可以降低分位数,这就是我在这里尝试做的。

import pandas as pd

quantiled, dict_bins = recursive_lower_labels(model_quant = model_quant,
                                              n_quantiles = n_quantiles,
                                              reverse = reverse)
def recursive_lower_labels(model_quant,
                           n_quantiles,
                           reverse = False):
    '''
    Recursively lowers the number of labels until it works.
    '''

    if n_quantiles == 0: # base case
        return 'Error: There are no Quantiles to be used.'

    # Not very important... 
    # I'm using this to either use normal or reverse labels.
    if reverse == False:
        labels = range(1, n_quantiles + 1)
    elif reverse == True:
        labels = range(n_quantiles, 0, -1)

    try:

        qt, dc = pd.qcut(model_quant, 
                         q = n_quantiles,
                         labels = labels,
                         retbins = True)

        return qt, dc

    except:

        recursive_lower_labels(model_quant,
                               n_quantiles = n_quantiles - 1,
                               reverse = reverse)

我遇到的错误是(指向顶部的函数调用):

  

无法解压缩不可迭代的NoneType对象

我怀疑这是我犯的两个错误之一:

  1. 在某处进行范围界定存在问题。也许n_quantiles?从我没有经验的调试看来,这似乎不太可能。
  2. except语句内的函数递归调用之前放置返回值存在问题。我在这里尝试了很多组合,即使最后加上一个额外的else也不起作用。

如果不是递归的话,这确实可行。

编辑

我的问题被标记为重复,此编辑旨在解决该评估问题。首先,它被标记为同样被标记为问题的重复,这很奇怪,但没有那么重要。与我的问题不同的重要且有用的概念是,它们都具有以下功能:尽管是递归的,但不一定总是返回某些东西,而我的确总是返回某些东西,因此,似乎递归的返回不必要-事实证明 not 是正确的。

1 个答案:

答案 0 :(得分:1)

您要做的就是返回您的递归。进行一些光重构:

def recursive_lower_labels(model_quant,
                           n_quantiles,
                           reverse=False):
    """
     Recursively lowers the number of labels until it works.
    """
    if n_quantiles == 0:  # base case
        return 'Error: There are no Quantiles to be used.'

    # Not very important...
    # I'm using this to either use normal or reverse labels.
    if reverse:
        labels = range(n_quantiles, 0, -1)
    else:
        labels = range(1, n_quantiles + 1)

    try:
        return pd.qcut(model_quant,
                         q=n_quantiles,
                         labels=labels,
                         retbins=True)

    except:
        return recursive_lower_labels(model_quant,
                                      n_quantiles=n_quantiles - 1,
                                      reverse=reverse)