pythonnumpyscipynanscipy.ndimage

scipy.ndimage.interpolation shift of numpy array gives erroneous result - bug?


This question is an extension of shift numpy array by row

If I shift (from scipy.ndimage.interpolation) using a test 3 x 5 x 5 array like so everything works as expected:

arr = np.ones([3,5,5])

array([[[ 1.,  1.,  1.,  1.,  1.],
        [ 1.,  1.,  1.,  1.,  1.],
        [ 1.,  1.,  1.,  1.,  1.],
        [ 1.,  1.,  1.,  1.,  1.],
        [ 1.,  1.,  1.,  1.,  1.]],

       [[ 1.,  1.,  1.,  1.,  1.],
        [ 1.,  1.,  1.,  1.,  1.],
        [ 1.,  1.,  1.,  1.,  1.],
        [ 1.,  1.,  1.,  1.,  1.],
        [ 1.,  1.,  1.,  1.,  1.]],

       [[ 1.,  1.,  1.,  1.,  1.],
        [ 1.,  1.,  1.,  1.,  1.],
        [ 1.,  1.,  1.,  1.,  1.],
        [ 1.,  1.,  1.,  1.,  1.],
        [ 1.,  1.,  1.,  1.,  1.]]])

shift(arr,(1,0,0), cval=np.nan)

array([[[ nan,  nan,  nan,  nan,  nan],
        [ nan,  nan,  nan,  nan,  nan],
        [ nan,  nan,  nan,  nan,  nan],
        [ nan,  nan,  nan,  nan,  nan],
        [ nan,  nan,  nan,  nan,  nan]],

       [[  1.,   1.,   1.,   1.,   1.],
        [  1.,   1.,   1.,   1.,   1.],
        [  1.,   1.,   1.,   1.,   1.],
        [  1.,   1.,   1.,   1.,   1.],
        [  1.,   1.,   1.,   1.,   1.]],

       [[  1.,   1.,   1.,   1.,   1.],
        [  1.,   1.,   1.,   1.,   1.],
        [  1.,   1.,   1.,   1.,   1.],
        [  1.,   1.,   1.,   1.,   1.],
        [  1.,   1.,   1.,   1.,   1.]]])

HOWEVER, if I perform the same shift on my 3 x 5 x 5 data array I get all np.nan values:

array([[[ 0.        ,         nan,         nan,         nan,         nan],
        [        nan,  0.        ,         nan,         nan, -1.07346633],
        [        nan,         nan,  0.        ,         nan,         nan],
        [        nan,         nan,         nan,  0.        ,         nan],
        [        nan,  1.07346633,         nan,         nan,  0.        ]],

       [[ 0.        ,         nan,         nan,         nan,         nan],
        [        nan,  0.        ,         nan,         nan,         nan],
        [        nan,         nan,  0.        , -1.44470265,         nan],
        [        nan,         nan,  1.44470265,  0.        ,         nan],
        [        nan,         nan,         nan,         nan,  0.        ]],

       [[ 0.        ,         nan,  1.80965682,         nan,         nan],
        [        nan,  0.        ,         nan,         nan,         nan],
        [-1.80965682,         nan,  0.        ,         nan,         nan],
        [        nan,         nan,         nan,  0.        ,         nan],
        [        nan,         nan,         nan,         nan,  0.        ]]])

shift(stats1_arr,(1,0,0), cval=np.nan)

array([[[ nan,  nan,  nan,  nan,  nan],
        [ nan,  nan,  nan,  nan,  nan],
        [ nan,  nan,  nan,  nan,  nan],
        [ nan,  nan,  nan,  nan,  nan],
        [ nan,  nan,  nan,  nan,  nan]],

       [[ nan,  nan,  nan,  nan,  nan],
        [ nan,  nan,  nan,  nan,  nan],
        [ nan,  nan,  nan,  nan,  nan],
        [ nan,  nan,  nan,  nan,  nan],
        [ nan,  nan,  nan,  nan,  nan]],

       [[ nan,  nan,  nan,  nan,  nan],
        [ nan,  nan,  nan,  nan,  nan],
        [ nan,  nan,  nan,  nan,  nan],
        [ nan,  nan,  nan,  nan,  nan],
        [ nan,  nan,  nan,  nan,  nan]]])

Am I doing something wrong (mis-using shift?) or is this a bug? Seems like a bug in scipy.ndimage.interpolation.shift


Solution

  • It's not a bug. According to the docs, it's using spline interpolation of order 3 (by default), and your sparse matrix just ends up full of np.nan values because you can't really interpolate it.

    You can essentially turn the interpolation 'feature' off by using order=0:

    shift(stats1_arr, (1, 0, 0), cval=np.nan, order=0)
    

    Which results in:

    array([[[     nan,      nan,      nan,      nan,      nan],
            [     nan,      nan,      nan,      nan,      nan],
            [     nan,      nan,      nan,      nan,      nan],
            [     nan,      nan,      nan,      nan,      nan],
            [     nan,      nan,      nan,      nan,      nan]],
    
           [[ 0.     ,      nan,      nan,      nan,      nan],
            [     nan,  0.     ,      nan,      nan, -1.07347],
            [     nan,      nan,  0.     ,      nan,      nan],
            [     nan,      nan,      nan,  0.     ,      nan],
            [     nan,  1.07347,      nan,      nan,  0.     ]],
    
           [[ 0.     ,      nan,      nan,      nan,      nan],
            [     nan,  0.     ,      nan,      nan,      nan],
            [     nan,      nan,  0.     , -1.4447 ,      nan],
            [     nan,      nan,  1.4447 ,  0.     ,      nan],
            [     nan,      nan,      nan,      nan,  0.     ]]])