# [Numpy-discussion] avoiding loops when downsampling arrays

Warren Weckesser warren.weckesser@enthought....
Mon Feb 6 15:10:58 CST 2012

```On Mon, Feb 6, 2012 at 2:57 PM, Sturla Molden <sturla@molden.no> wrote:

> Short answer: Create 16 view arrays, each with a stride of 4 in both
> dimensions. Test them against the conditions and combine the tests with an
> |= operator. Thus you replace the nested loop with one that has only 16
> iterations. Or reshape to 3 dimensions, the last with length 4, and you can
> do the same with only four view arrays.
>
> Sturla
>
>

Or use 'as_strided' from the stride_tricks module:

import numpy as np
from numpy.lib.stride_tricks import as_strided

# Make some demonstration data.
a = np.random.random_integers(0, 99, size=(12,16))

# Find 4x4 blocks whose values are between these limits.
low = 5
high = 94

# Make a 4D view of this data, such that b[i,j]
# is a 2D block with shape (4,4) (e.g. b[0,0] is
# the same as a[:4, :4]).
b = as_strided(a, shape=(a.shape[0]/4, a.shape[1]/4, 4, 4),
strides=(4*a.strides[0], 4*a.strides[1], a.strides[0],
a.strides[1]))

# Reduce this to a 2D array of boolean values.  The value is
# True if the corresponding 4x4 block contains only values
# between low and high (inclusive).
result = np.all(np.all((b >= low) & (b <= high), axis=-1), axis=-1)

print a
print result

Output (from ipython)t:

In [111]: run 2Dto4by4blocks.py
[[ 5 50 62 43 52 21 67 70 55 12 25 21  1 95 73 31]
[44  4 60 27 93 54 25 87 15 22 37 31 46 84 10 46]
[35 26 11 76 91 79 58 92 57 62 27 27 17 19 39 86]
[94 96 21 36 90 18 80 62 91 68 39 22 68 31 71 48]
[89 34 52 80 93 73 54 13 25 28 57 32 55 42  3 13]
[65 68 41 82 55 81 64 59 73  4 44 46 91  1 86 52]
[99 87 21 70 26 64  2 10 62 82 52 67 85 88 45 53]
[33 10  6  3 46 71 17 58 20 56 30 18 19 17 60 76]
[18 22 62 53 45 21 83 86 69 35 32 36 33 74 81 70]
[24 39 93 12 37  4  4 16 45 59 46  4 90 24  1 13]
[26 37 11 11 24 58  6 44 43 44 94 55 22  8  7 85]
[26 91 31 75 72 25 23 89  3 30 45 93 62 72 96 39]]
[[False  True  True False]
[False False False False]
[ True False False False]]

Warren

>
> Den 6. feb. 2012 kl. 20:16 skrev "Moroney, Catherine M (388D)" <
> Catherine.M.Moroney@jpl.nasa.gov>:
>
> > Hello,
> >
> > I have to write a code to downsample an array in a specific way, and I
> am hoping that
> > somebody can tell me how to do this without the nested do-loops.  Here
> is the problem
> > statement:  Segment a (MXN) array into 4x4 squares and set a flag if any
> of the pixels
> > in that 4x4 square meet a certain condition.
> >
> > Here is the code that I want to rewrite avoiding loops:
> >
> > shape_out = (data_in.shape[0]/4, data_in.shape[1]/4)
> > found = numpy.zeros(shape_out).astype(numpy.bool)
> >
> > for i in xrange(0, shape_out[0]):
> >    for j in xrange(0, shape_out[1]):
> >
> >        excerpt = data_in[i*4:(i+1)*4, j*4:(j+1)*4]
> >        mask = numpy.where( (excerpt >= t1) & (excerpt <= t2), True,
> False)
> >            found[i,j] = True
> >
> > Thank you for any hints and education!
> >
> > Catherine
> > _______________________________________________
> > NumPy-Discussion mailing list
> > NumPy-Discussion@scipy.org
> > http://mail.scipy.org/mailman/listinfo/numpy-discussion
> _______________________________________________
> NumPy-Discussion mailing list
> NumPy-Discussion@scipy.org
> http://mail.scipy.org/mailman/listinfo/numpy-discussion
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.scipy.org/pipermail/numpy-discussion/attachments/20120206/8aa9784f/attachment.html
```