捕获numpy运行时警告作为异常并抑制它们

时间:2017-08-11 09:34:04

标签: python json numpy exception warnings

我知道已经部分回答here

无论如何,我不确定我是否达到了我的目标。我将简要解释一下我在做什么:

  • 阅读一个特别的json文件列表 嵌套结构。
  • 从中提取最低级别的值,并在这些值为列表时取平均值。
  • 将这些值收集到numpy数组中。
  • 将我的numpy数组转换为pickle文件。

一切都很顺利,但我收到了一些numpy运行时警告:

  • RuntimeWarning: Mean of empty slice.
  • RuntimeWarning: invalid value encountered in double_scalars

给我带来麻烦的功能是实际提取执行此操作的值的人:v = np.mean(v)

我知道错误可能是由零列表或某些NaN / Inf或其他值引起的。

我想通过从我的数据集中丢弃当前的.json样本来摆脱它们。

所以我设置了np.seterr(all='warn')

我制作了这个笨拙的代码试图抓住它:

def ExtracValues(d):
    for v in d.values():
        if isinstance(v, dict):
            yield from ExtracValues(v)
        else:
            if isinstance(v,list):
                # v = np.mean(v)            #just averaging vectorial values of features.   #it may be here that raises the empty slice warning of numpy.
                try:
                    v = np.mean(v)
                except Warning:
                    return #trying to trash samples which are no behaving good                  
            yield v

我的问题是我不知道它是否有效地工作,因为警告仍然印在stdout上。我想在设置all="Warning"后代码应该已停止,但我怎么能轻易检查我是否正确?

此外,是否有更多pythonic方法来缩短该功能。我真的不喜欢以这种方式嵌套的try/except

1 个答案:

答案 0 :(得分:1)

感谢JürgMerlinSpaak的评论,我找到了一个更好,更简单的解决方案。在函数之外捕获异常显然更好,我恢复到原始版本:

def ExtractValues(d):
    for v in d.values():
        if isinstance(v, dict):
            yield from ExtractValues(v)
        else:
            if isinstance(v,list):
                v = np.mean(v)  
            yield v

我已经在代码的主要内容中设置了所有内容:

np.seterr(all='warn')

然后抓住他们:

with warnings.catch_warnings():
                    warnings.filterwarnings('error')
                    try:
                        raw_features = list(ExtractValues(data)) 
                    except Warning as e:
                        print('Houston, we have a warning:', e)
                        print('The bad guy is: ' + current_file)
                        print('This sample will not be considered.')
                        pass
                    else:
                        #Whatever

值得注意的是,无论谁来到这里同样的例外。我成功捕获了两个警告,但print(e)只会告诉你“空切片的意思”。我可以猜到为什么,但我太累了,无法进一步调查。