Tengo el siguiente código:

def chunk_trades(A):
    last = A[0]
    new = []
    for x in A.iteritems():
        if np.abs((x[1]-last)/last) > 0.1:
            new.append(x[1])
            last = x[1]
        else:
            new.append(last)
    s = pd.Series(new, index=A.index)
    return s

Algunas veces last puede ser cero. En este caso, me gustaría que continúe con gracia como si last fuera casi cero.

¿Cuál es la forma más limpia?

2
cjm2671 28 jun. 2016 a las 13:20

3 respuestas

La mejor respuesta

Simplemente reemplace su línea por esto:

if not last or np.abs((x[1]-last)/last) > 0.1:

Esto no generará una excepción ya que la aserción izquierda se verifica primero.

1
YOBA 28 jun. 2016 a las 10:40

Si entiendo correctamente, cuando last == 0 obtendrás ZeroDivisionError, ¿no? En caso afirmativo, considere la siguiente versión ligeramente modificada de su código:

def chunk_trades(A):
    last = A[0]
    new = []
    for x in A.iteritems():
        try:
            if np.abs((x[1]-last)/last) > 0.1:
                new.append(x[1])
                last = x[1]
            else:
                new.append(last)
        except ZeroDivisionError:
            eps = 1e-18 # arbitary infinitesmall number
            last = last + eps
            if np.abs((x[1]-last)/last) > 0.1:
                new.append(x[1])
                last = x[1]
            else:
                new.append(last)

    s = pd.Series(new, index=A.index)
    return s
0
Mikhail T. 28 jun. 2016 a las 10:37

No estoy seguro de si realmente desea dividir entre "casi 0", ya que el resultado será "casi infinito", pero también puede hacer esto:

if last == 0:
   last = sys.float_info.min

Este es el flotador normalizado positivo mínimo, es decir, el valor más cercano a cero.

Fuente: https://docs.python.org/2/library/sys .html # sys.float_info

1
advance512 28 jun. 2016 a las 10:32