[Numpy-discussion] ENH: Proposal to add atleast_nd function

Sebastian Berg sebastian at sipsolutions.net
Wed Feb 10 17:48:30 EST 2021


On Wed, 2021-02-10 at 17:31 -0500, Joseph Fox-Rabinovitz wrote:
> I've created PR#18386 to add a function called atleast_nd to numpy
> and
> numpy.ma. This would generalize the existing atleast_1d, atleast_2d,
> and
> atleast_3d functions.
> 
> I proposed a similar idea about four and a half years ago:
> https://mail.python.org/pipermail/numpy-discussion/2016-July/075722.html
> ,
> PR#7804. The reception was ambivalent, but a couple of folks have
> asked me
> about this, so I'm bringing it back.
> 
> Some pros:
> 
> - This closes issue #12336
> - There are a couple of Stack Overflow questions that would benefit
> - Been asked about this a couple of times
> - Implementation of three existing atleast_*d functions gets easier
> - Looks nicer that the equivalent broadcasting and reshaping
> 
> Some cons:
> 
> - Cluttering up the API
> - Maintenance burden (but not a big one)
> - This is just a utility function, which can be achieved through
> broadcasting and reshaping
> 

My main concern would be the namespace cluttering. I can't say I use
even the `atleast_2d` etc. functions personally, so I would tend to be
slightly against the addition. But if others land on the "useful" side
here (and it seemed a bit at least on github), I am also not opposed.
 It is a clean name that lines up with existing ones, so it doesn't
seem like a big "mental load" with respect to namespace cluttering.

Bike shedding the API is probably a good idea in any case.

I have pasted the current PR documentation (as html) below for quick
reference. I wonder a bit about the reasoning for having `pos` specify
a value rather than just a side?



numpy.atleast_nd(ary, ndim, pos=0)
View input as array with at least ndim dimensions.
New unit dimensions are inserted at the index given by pos if
necessary.
Parameters
ary  array_like
The input array. Non-array inputs are converted to arrays. Arrays that
already have ndim or more dimensions are preserved.

ndim  int
The minimum number of dimensions required.

pos  int, optional
The index to insert the new dimensions. May range from -ary.ndim -
 1 to +ary.ndim (inclusive). Non-negative indices indicate locations
before the corresponding axis: pos=0 means to insert at the very
beginning. Negative indices indicate locations after the corresponding
axis: pos=-1 means to insert at the very end. 0 and -1 are always
guaranteed to work. Any other number will depend on the dimensions of
the existing array. Default is 0.



Returns
res  ndarray
An array with res.ndim >= ndim. A view is returned for array inputs.
Dimensions are prepended if pos is 0, so for example, a 1-D array of
shape (N,) with ndim=4becomes a view of shape (1, 1, 1, N). Dimensions
are appended if pos is -1, so for example a 2-D array of
shape (M, N) becomes a view of shape (M, N, 1, 1)when ndim=4.



See also
atleast_1d, atleast_2d, atleast_3d


Notes
This function does not follow the convention of the
other atleast_*d functions in numpy in that it only accepts a single
array argument. To process multiple arrays, use a comprehension or loop
around the function call. See examples below.
Setting pos=0 is equivalent to how the array would be interpreted by
numpy’s broadcasting rules. There is no need to call this function for
simple broadcasting. This is also roughly (but not exactly) equivalent
to np.array(ary, copy=False, subok=True, ndmin=ndim).
It is easy to create functions for specific dimensions similar to the
other atleast_*d functions using Python’s functools.partial function.
An example is shown below.
Examples
>>> np.atleast_nd(3.0, 4)
array([[[[ 3.]]]])
>>> x = np.arange(3.0)
>>> np.atleast_nd(x, 2).shape
(1, 3)
>>> x = np.arange(12.0).reshape(4, 3)
>>> np.atleast_nd(x, 5).shape
(1, 1, 1, 4, 3)
>>> np.atleast_nd(x, 5).base is x.base
True
>>> [np.atleast_nd(x) for x in ((1, 2), [[1, 2]], [[[1, 2]]])]:
[array([[1, 2]]), array([[1, 2]]), array([[[1, 2]]])]
>>> np.atleast_nd((1, 2), 5, pos=0).shape
(1, 1, 1, 1, 2)
>>> np.atleast_nd((1, 2), 5, pos=-1).shape
(2, 1, 1, 1, 1)
>>> from functools import partial
>>> atleast_4d = partial(np.atleast_nd, ndim=4)
>>> atleast_4d([1, 2, 3])
[[[[1, 2, 3]]]]


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.python.org/pipermail/numpy-discussion/attachments/20210210/3d0ee91b/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: This is a digitally signed message part
URL: <https://mail.python.org/pipermail/numpy-discussion/attachments/20210210/3d0ee91b/attachment-0001.sig>


More information about the NumPy-Discussion mailing list