[Numpy-discussion] Add sliding_window_view method to numpy
Zimmermann Klaus
klaus.zimmermann at smhi.se
Tue Oct 13 05:18:32 EDT 2020
Hi,
thanks, Sebastian! Since `sliding_window_view` is essentially a small
function determining the parameters with which to call `as_strided`, it
makes sense to me to keep the essential `as_strided` parameters, `subok`
among them. But if somebody with a deeper insight into numpy is
convinced this should go, I have no problem with it.
Cheers
Klaus
On 12/10/2020 17:25, Sebastian Berg wrote:
> On Mon, 2020-10-12 at 08:39 +0000, Zimmermann Klaus wrote:
>> Hello,
>>
>> I would like to draw the attention of this list to PR #17394 [1] that
>> adds the implementation of a sliding window view to numpy.
>>
>
> Hi,
>
> thanks for working on this and driving going forward. I like the choice
> of a minimal API. I have pasted the doc-string (html, hope that works
> fine) below to allow a quicker idea of what is being proposed. To me it
> looks good! (I wonder if we need `subok`, but I guess we probably do.)
>
> Cheers,
>
> Sebastian
>
>
> numpy.sliding_window_view<https://16171-908607-gh.circle-artifacts.com/0/doc/build/html/reference/generated/numpy.sliding_window_view.html#numpy-sliding-window-view>
>
>
> |numpy.||sliding_window_view|(/x/, /window_shape/, /axis=None/, /*/, /subok=False/, /writeable=False/)<https://16171-908607-gh.circle-artifacts.com/0/doc/build/html/reference/generated/numpy.sliding_window_view.html#numpy.sliding_window_view>
>
> Create a sliding window view into the array with the given window
> shape.
>
> Creates a sliding window view of the N dimensional array with the
> given window shape. Window slides across each dimension of the
> array and extract a subsets of the array at any window position.
>
> Parameters
>
> x : array_like
>
> Array to create the sliding window view from.
>
> window_shape : int or tuple of int
>
> Size of window over each axis that takes part in the
> sliding window. If /axis/ is not present, must have same
> length as the number of input array dimensions. Single
> integers /i/ are treated as if they were the tuple /(i,)/.
>
> axis : int or tuple of int, optional
>
> Axis or axes along which the sliding window is applied. By
> default, the sliding window is applied to all axes
> and /window_shape[i]/ will refer to axis /i/ of /x/.
> If /axis/ is given as a /tuple of
> int/, /window_shape[i]/ will refer to the
> axis /axis[i]/ of /x/. Single integers /i/ are treated as
> if they were the tuple /(i,)/.
>
> subok : bool, optional
>
> If True, sub-classes will be passed-through, otherwise the
> returned array will be forced to be a base-class array
> (default).
>
> writeable : bool, optional
>
> When true, allow writing to the returned view. The default
> is false, as this should be used with caution: the
> returned view contains the same memory location multiple
> times, so writing to one location will cause others to change.
>
> Returns
>
> view : ndarray
>
> Sliding window view of the array. The sliding window
> dimensions are inserted at the end, and the original
> dimensions are trimmed as required by the size of the
> sliding window.
>
> That is, |view.shape = x_shape_trimmed + window_shape|,
> where |x_shape_trimmed| is |x.shape| with every entry
> reduced by one less than the corresponding window size.
>
> See also
>
> |lib.stride_tricks.as_strided|
> <https://16171-908607-gh.circle-artifacts.com/0/doc/build/html/reference/generated/numpy.lib.stride_tricks.as_strided.html#numpy.lib.stride_tricks.as_strided>
>
> Create a view into the array with the given shape and strides.
>
> |broadcast_to|
> <https://16171-908607-gh.circle-artifacts.com/0/doc/build/html/reference/generated/numpy.broadcast_to.html#numpy.broadcast_to>
>
> broadcast an array to a given shape.
>
> Notes
>
> For some cases there may be more efficient approaches to calculate
> transformations across multi-dimensional arrays, for
> instance |scipy.signal.fftconvolve|
> <https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.fftconvolve.html#scipy.signal.fftconvolve>,
> where combining the iterating step with the calculation itself
> while storing partial results can result in significant speedups.
>
> Examples
>
> >>> x = np.arange(6)
> >>> x.shape
> (6,)
> >>> v = np.sliding_window_view(x, 3)
> >>> v.shape
> (4, 3)
> >>> v
> array([[0, 1, 2],
> [1, 2, 3],
> [2, 3, 4],
> [3, 4, 5]])
>
> This also works in more dimensions, e.g.
>
> >>> i, j = np.ogrid[:3, :4]
> >>> x = 10*i + j
> >>> x.shape
> (3, 4)
> >>> x
> array([[ 0, 1, 2, 3],
> [10, 11, 12, 13],
> [20, 21, 22, 23]])
> >>> shape = (2,2)
> >>> v = np.sliding_window_view(x, shape)
> >>> v.shape
> (2, 3, 2, 2)
> >>> v
> array([[[[ 0, 1],
> [10, 11]],
> [[ 1, 2],
> [11, 12]],
> [[ 2, 3],
> [12, 13]]],
> [[[10, 11],
> [20, 21]],
> [[11, 12],
> [21, 22]],
> [[12, 13],
> [22, 23]]]])
>
> The axis can be specified explicitly:
>
> >>> v = np.sliding_window_view(x, 3, 0)
> >>> v.shape
> (1, 4, 3)
> >>> v
> array([[[ 0, 10, 20],
> [ 1, 11, 21],
> [ 2, 12, 22],
> [ 3, 13, 23]]])
>
> The same axis can be used several times. In that case, every use
> reduces the corresponding original dimension:
>
> >>> v = np.sliding_window_view(x, (2, 3), (1, 1))
> >>> v.shape
> (3, 1, 2, 3)
> >>> v
> array([[[[ 0, 1, 2],
> [ 1, 2, 3]]],
> [[[10, 11, 12],
> [11, 12, 13]]],
> [[[20, 21, 22],
> [21, 22, 23]]]])
>
> Combining with stepped slicing (/::step/), this can be used to
> take sliding views which skip elements:
>
> >>> x = np.arange(7)
> >>> np.sliding_window_view(x, 5)[:, ::2]
> array([[0, 2, 4],
> [1, 3, 5],
> [2, 4, 6]])
>
> or views which move by multiple elements
>
> >>> x = np.arange(7)
> >>> np.sliding_window_view(x, 3)[::2, :]
> array([[0, 1, 2],
> [2, 3, 4],
> [4, 5, 6]])
>
>
>
>
>
>> Having a sliding window view in numpy is a longstanding open issue (cf
>> #7753 [2] from 2016). A brief summary of the discussions surrounding it
>> can be found in the description of the PR.
>>
>> This PR implements a sliding window view based on stride tricks.
>> Following the discussion in issue #7753, a first implementation was
>> provided by Fanjin Zeng in PR #10771. After some discussion, that PR
>> stalled and I picked up the issue in the present PR #17394. It is based
>> on the first implementation, but follows the changed API as suggested by
>> Eric Wieser.
>>
>> Code reviews have been provided by Bas van Beek, Stephen Hoyer, and Eric
>> Wieser. Sebastian Berg added the "62 - Python API" label.
>>
>>
>> Do you think this is suitable for inclusion in numpy?
>>
>> Do you consider the PR ready?
>>
>> Do you have suggestions or requests?
>>
>>
>> Thanks for your time and consideration!
>> Klaus
>>
>>
>> [1] https://github.com/numpy/numpy/pull/17394
>> <https://github.com/numpy/numpy/pull/17394>
>> [2] https://github.com/numpy/numpy/issues/7753
>> <https://github.com/numpy/numpy/issues/7753>
>> _______________________________________________
>> NumPy-Discussion mailing list
>> NumPy-Discussion at python.org <mailto:NumPy-Discussion at python.org>
>> https://mail.python.org/mailman/listinfo/numpy-discussion
>> <https://mail.python.org/mailman/listinfo/numpy-discussion>
>>
>
>
> _______________________________________________
> NumPy-Discussion mailing list
> NumPy-Discussion at python.org
> https://mail.python.org/mailman/listinfo/numpy-discussion
>
More information about the NumPy-Discussion
mailing list