[Python] Strange numpy divide behaviour for scalars

Discussão em 'Python' iniciado por Stack, Agosto 13, 2025.

  1. Stack

    Stack Membro Participativo

    I have been trying to upgrade a library which has a bunch of geometric operations for scalars so they will work with numpy arrays as well. While doing this I noticed some strange behaviour with numpy divide.

    In original code checks a normalised difference between to variables if neither variable is zero, swapping across to numpy this ended up looking something like:

    import numpy as np

    a = np.array([0, 1, 2, 3, 4])
    b = np.array([1, 2, 3, 0, 4])

    o = np.zeros(len(a))
    o = np.divide(np.subtract(a, b), b, out=o, where=np.logical_and(a != 0, b != 0))
    print(f'First implementation: {o}')


    where I passed in a output buffer initialised to zero for instances which could not be calculated; this returns:

    First implementation: [ 0. -0.5 -0.33333333 0. 0. ]


    I had to slightly modify this for scalars as out required an array, but it seemed fine.

    a = 0
    b = 4
    o = None if np.isscalar(a) else np.zeros(len(a))
    o = np.divide(np.subtract(a, b), b, out=o, where=np.logical_and(b != 0, a != 0))
    print(f'Modified out for scalar: {o}')


    returns

    Modified out for scalar: 0.0.


    Then ran this through some test functions and found a lot of them failed. Digging into this, I found that the first time I call the divide with a scalar with where set to False the function returns zero, but if I called it again, the second time it returns something unpredictable.

    a = 0
    b = 4
    print(f'First divide: {np.divide(b, a, where=False)}')
    print(f'Second divide: {np.divide(b, a, where=False)}')


    returns

    First divide: 0.0
    Second divide: 4.0


    Looking at the documentation, it says "locations within it where the condition is False will remain uninitialized", so I guess numpy as some internal buffer which is initially set to zero then subsequently it ends up carrying over an earlier intermediate value.

    I am struggling to see how I can use divide with or without a where clause; if I use where I get an unpredictable output and if I don't I can't protect against divide by zero. Am I missing something or do I just need to have a different code path in these cases? I realise I'm half way to a different code path already with the out variable.

    I would be grateful for any advice.

    Continue reading...

Compartilhe esta Página