I totally agree with the namespace clutter concern, but honestly, I would use 
`atleast_nd` with its `pos` argument (I might rename it to `position`, `axis`, 
or `axis_position`) any day over `at_least{1,2,3}d`, for which I had no idea 
where the new axes would end up.

So, I’m in favour of including it, and optionally deprecating 
`atleast_{1,2,3}d`.

Juan.

> On 11 Feb 2021, at 9:48 am, Sebastian Berg <sebast...@sipsolutions.net> wrote:
> 
> 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 
>> <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 
> <https://18298-908607-gh.circle-artifacts.com/0/doc/build/html/reference/generated/numpy.atleast_1d.html#numpy.atleast_1d>,
>  atleast_2d 
> <https://18298-908607-gh.circle-artifacts.com/0/doc/build/html/reference/generated/numpy.atleast_2d.html#numpy.atleast_2d>,
>  atleast_3d 
> <https://18298-908607-gh.circle-artifacts.com/0/doc/build/html/reference/generated/numpy.atleast_3d.html#numpy.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 
> <https://docs.python.org/dev/library/functools.html#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]]]]
> 
> _______________________________________________
> NumPy-Discussion mailing list
> NumPy-Discussion@python.org <mailto:NumPy-Discussion@python.org>
> https://mail.python.org/mailman/listinfo/numpy-discussion 
> <https://mail.python.org/mailman/listinfo/numpy-discussion>
_______________________________________________
NumPy-Discussion mailing list
NumPy-Discussion@python.org
https://mail.python.org/mailman/listinfo/numpy-discussion

Reply via email to