[Numpy-discussion] Reductions with nditer working only with the last axis

Sergio Pascual sergiopr@fis.ucm...
Mon Oct 1 17:01:05 CDT 2012


Perhaps sum wasn't the best function for this example. I'm going to
rework the code with other function

Consider a function that operates on an array and returns a number

def myfunc(data):
    return data.min() + 2 * data.max()

The function with nditer is:

def nditer_fun(data, axes):
    it = numpy.nditer([data, None],
                flags=['reduce_ok', 'external_loop'],
                op_flags=[['readonly'], ['readwrite', 'allocate']],
                    op_axes=[None, axes])
    it.operands[1][...] = 0

    for x, y in it:
        y[...] = myfun(x)

    return it.operands[1]

We can compara the result of this function with the result of
numpy.apply_along_axis
With the data

data = numpy.arange(2*3*4).reshape((2,3,4))

the values obtained with axis 0 ara

numpy.apply_along_axis(myfun, 0 ,data)
[[24 27 30 33]
 [36 39 42 45]
 [48 51 54 57]]

nditer_fun(data, [-1, 0, 1])
[[58 58 58 58]
 [58 58 58 58]
 [58 58 58 58]]

Only along the last axis both functions give the same result


2012/10/1 Han Genuit <hangenuit@gmail.com>:
> On Thu, Sep 27, 2012 at 6:08 PM, Sergio Pascual <sergio.pasra@gmail.com> wrote:
>> Hello, I'm trying to understand how to work with nditer to do a
>> reduction, in my case converting a 3d array into a 2d array.
>>
>> I followed the help here
>> http://docs.scipy.org/doc/numpy/reference/arrays.nditer.html and
>> managed to create a function that applies reduction over the last axis
>> of the input. With this function
>>
>> def nditer_sum(data, red_axes):
>>     it = numpy.nditer([data, None],
>>                 flags=['reduce_ok', 'external_loop'],
>>                 op_flags=[['readonly'], ['readwrite', 'allocate']],
>>                 op_axes=[None, red_axes])
>>     it.operands[1][...] = 0
>>
>>     for x, y in it:
>>         y[...] = x.sum()
>>
>>     return it.operands[1]
>>
>> I can get something equivalent to data.sum(axis=2)
>>
>>>>> data = numpy.arange(2*3*4).reshape((2,3,4))
>>>>> nditer_sum(data, [0, 1, -1])
>> [[ 6 22 38]
>>  [54 70 86]]
>>>>> data.sum(axis=2)
>> [[ 6 22 38]
>>  [54 70 86]]
>>
>> So to get something equivalent to data.sum(axis=0) I though that it
>> was enough to change  the argument red_axes to [-1, 0,1]
>> But the result is quite different.
>>
>>>>> data = numpy.arange(2*3*4).reshape((2,3,4))
>>>>> data.sum(axis=0)
>> [[12 14 16 18]
>>  [20 22 24 26]
>>  [28 30 32 34]]
>>>>> nditer_sum(data, [-1, 0, 1])
>> [[210 210 210 210]
>>  [210 210 210 210]
>>  [210 210 210 210]]
>>
>> In the for loop inside nditer_sum (for x,y in it:), the iterator is
>> looping 2 times and giving an array of length 12 each time, instead of
>> looping 12 times and giving an array of length 2 each time. I have
>> read the numpy documentation several times and googled about this to
>> no avail.
>>
>> Does anybody have an example of a reduction in the first axis of an
>> array using nditer? Is this a bug?
>>
>>
>> Regards, Sergio
>> _______________________________________________
>> NumPy-Discussion mailing list
>> NumPy-Discussion@scipy.org
>> http://mail.scipy.org/mailman/listinfo/numpy-discussion
>
> The example from the link it shows how to do a reduction with y[...]
> += x. If you would replace x.sum() by += x, then it works.
>
>>>> nditer_sum(data, [-1,0,1])
> array([[12, 14, 16, 18],
>        [20, 22, 24, 26],
>        [28, 30, 32, 34]])
>>>> data.sum(axis=0)
> array([[12, 14, 16, 18],
>        [20, 22, 24, 26],
>        [28, 30, 32, 34]])
>
>>>> nditer_sum(data, [0,-1,1])
> array([[12, 15, 18, 21],
>        [48, 51, 54, 57]])
>>>> data.sum(axis=1)
> array([[12, 15, 18, 21],
>        [48, 51, 54, 57]])
>
> I think that is because sum() already reduces all axis by default.
>
> Regards,
> Han
> _______________________________________________
> NumPy-Discussion mailing list
> NumPy-Discussion@scipy.org
> http://mail.scipy.org/mailman/listinfo/numpy-discussion



-- 
Sergio Pascual     http://guaix.fis.ucm.es/~spr    +34 91 394 5018
gpg fingerprint: 5203 B42D 86A0 5649 410A F4AC A35F D465 F263 BCCC
Departamento de Astrofísica -- Universidad Complutense de Madrid (Spain)


More information about the NumPy-Discussion mailing list