Try/except 仍然在 try 块中抛出错误

Try/except still throws error in try block

当 运行 来自 https://github.com/Ecogenomics/GroopM 的 groopm 程序时,我遇到了以下错误:

Unexpected error: <type 'exceptions.FloatingPointError'>
Traceback (most recent call last):
  File "/home/mathed/virtualenv/groopm_env/bin/groopm", line 381, in <module>
    GM_parser.parseOptions(args)
  File "/home/mathed/virtualenv/groopm_env/local/lib/python2.7/site-packages/groopm/groopm.py", line 138, in parseOptions
    gf=gf)
  File "/home/mathed/virtualenv/groopm_env/local/lib/python2.7/site-packages/groopm/cluster.py", line 217, in makeCores
    self.RE.refineBins(self.timer, auto=True, saveBins=False, plotFinal=prfx, gf=gf)
  File "/home/mathed/virtualenv/groopm_env/local/lib/python2.7/site-packages/groopm/refine.py", line 158, in refineBins
    graph = self.autoRefineBins(timer, makeGraph=gf!="")
  File "/home/mathed/virtualenv/groopm_env/local/lib/python2.7/site-packages/groopm/refine.py", line 474, in autoRefineBins
    self.mergeSimilarBins(graph=graph, verbose=False)
  File "/home/mathed/virtualenv/groopm_env/local/lib/python2.7/site-packages/groopm/refine.py", line 571, in mergeSimilarBins
    mergers = self.findMergeGroups(kCutMedian, kCutStd, cCutMedian, cCutStd, verbose=verbose)
  File "/home/mathed/virtualenv/groopm_env/local/lib/python2.7/site-packages/groopm/refine.py", line 631, in findMergeGroups
    retA=True)
  File "/home/mathed/virtualenv/groopm_env/local/lib/python2.7/site-packages/groopm/bin.py", line 352, in getBoundingKEllipseArea
    (A, center, radii, _rotation) = ET.getMinVolEllipse(KPCAs, retA=True)
  File "/home/mathed/virtualenv/groopm_env/local/lib/python2.7/site-packages/groopm/ellipsoid.py", line 112, in getMinVolEllipse
    (A, center, radii, rotation) = self.getMinVolEllipse(PP, retA=True)
  File "/home/mathed/virtualenv/groopm_env/local/lib/python2.7/site-packages/groopm/ellipsoid.py", line 112, in getMinVolEllipse
    (A, center, radii, rotation) = self.getMinVolEllipse(PP, retA=True)
  File "/home/mathed/virtualenv/groopm_env/local/lib/python2.7/site-packages/groopm/ellipsoid.py", line 153, in getMinVolEllipse
    radii = 1.0/np.sqrt(s)
FloatingPointError: divide by zero encountered in divide

在 ellipsoid.py,从第 151 行开始,我有:

        try:
            U, s, rotation = linalg.svd(A)
            radii = 1.0/np.sqrt(s)
        except np.linalg.linalg.LinAlgError:
            # hack -> better than crashing...
            rotation = np.eye(3)
            radii = np.ones(3)

ellipsoidtool 整个代码如下所示:

class EllipsoidTool:
    """Some stuff for playing with ellipsoids"""
    def __init__(self): pass

    def getMinVolEllipse(self, P, tolerance=0.01, retA=False):
        """ Find the minimum volume ellipsoid which holds all the points

        Based on work by Nima Moshtagh
        http://www.mathworks.com/matlabcentral/fileexchange/9542
        and also by looking at:
        http://cctbx.sourceforge.net/current/python/scitbx.math.minimum_covering_ellipsoid.html
        Which is based on the first reference anyway!

        Here, P is a numpy array of 3D points like this:
        P = [[x,y,z],
             [x,y,z],
             [x,y,z]]

        Returns:
        (center, radii, rotation)

        """
        (N, d) = np.shape(P)

        # Q will be out working array
        Q = np.copy(P.T)
        Q = np.vstack([Q, np.ones(N)])
        QT = Q.T

        # initializations
        err = 1 + tolerance
        u = np.array([1.0 / N for i in range(N)]) # first iteration

        # Khachiyan Algorithm
        singular = False
        while err > tolerance:
            V = np.dot(Q, np.dot(np.diag(u), QT))
            try:
                M = np.diag(np.dot(QT , np.dot(linalg.inv(V), Q)))    # M the diagonal vector of an NxN matrix
            except linalg.linalg.LinAlgError:
                # most likely a singular matrix
                # permute the values a little and then we'll try again
                from random import random, randint
                PP = np.copy(P)
                for i in range(N):
                    if randint(0,3) == 0:
                        j = randint(0,2)
                        if randint(0,1) != 0:
                            PP[i,j] += random()
                        else:
                            PP[i,j] -= random()
                (A, center, radii, rotation) = self.getMinVolEllipse(PP, retA=True)
                singular = True
                break

            j = np.argmax(M)
            maximum = M[j]
            step_size = (maximum - d - 1.0) / ((d + 1.0) * (maximum - 1.0))
            new_u = (1.0 - step_size) * u
            new_u[j] += step_size
            err = np.linalg.norm(new_u - u)
            u = new_u

        if not singular:
            # center of the ellipse
            center = np.dot(P.T, u)

            # the A matrix for the ellipse
            try:
                A = linalg.inv(
                               np.dot(P.T, np.dot(np.diag(u), P)) -
                               np.array([[a * b for b in center] for a in center])
                               ) / d
            except linalg.linalg.LinAlgError:
                # the matrix is singular so we need to return a degenerate ellipse
                #print '[Notice] Degenerate ellipse constructed indicating a bin with extremely small coverage divergence.'
                center = np.mean(P, axis=0)
                radii = np.max(P,axis=0) - np.min(P, axis=0)

                if len(P[0]) == 3:
                    rotation = [[0,0,0],[0,0,0],[0,0,0]]
                else:
                    rotation = [[0,0],[0,0]]

                if retA:
                    return (None, center, radii, rotation)
                else:
                    return (center, radii, rotation)

            # Get the values we'd like to return
            try:
                U, s, rotation = linalg.svd(A)
                radii = 1.0/np.sqrt(s)
            except np.linalg.linalg.LinAlgError:
                # hack -> better than crashing...
                rotation = np.eye(3)
                radii = np.ones(3)
        else:
            # hack -> better than crashing...
            rotation = np.eye(3)
            radii = np.ones(3)
        if retA:
            return (A, center, radii, rotation)
        else:
            return (center, radii, rotation)

我不确定为什么它会给我一个错误,即使代码在 try 块中。有没有办法来解决这个问题?

谢谢。

您的 except 块不处理引发的错误。它设置为处理 np.linalg.linalg.LinAlgError,但引发的错误是 FloatingPointError.

更改您的代码以捕获任一异常:

try:
    U, s, rotation = linalg.svd(A)
    radii = 1.0/np.sqrt(s)
except (np.linalg.linalg.LinAlgError, FloatingPointError):
    # hack -> better than crashing...
    rotation = np.eye(3)
    radii = np.ones(3)

如果有或者一个np.linalg.linalg.LinAlgError或者一个FloatingPointError.[=17,except块现在将运行 =]