You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The following patterns are quite common [1]: x = np.r_(x[0], x, x[-1]) and x = np.r_[0, x]. Neither of these can be directly replaced by xp.concat because the latter requires that The arrays must have the same shape, except in the dimension specified by axis.
The most common case IME is that x is a 1D array, which gets appended or prepended by a scalar.
An Array API replacement is something along the lines of
def npr(xp, *arys):
arys = [xp.asarray(a) for a in arys]
arys = [xpx.atleast_nd(a, ndim=1, xp=xp) for a in arys]
return xp.concat(arys)
which requires array_api_extra and is generally a bit clunky. There was at least one case where a scipy change which was missing atleast_1d broke jax.scipy.
Allowing 0D arrays and python scalars in concat would obviate the need for these sorts of helpers.
Yes, numpy's concatenate is limited by what is in this guidance. Numpy, however, has np.r_, which --- with all is sins --- allows extending arrays with scalars or 0D arrays. And this is what's missing in the array API land.
I think np.concat is not limited by this guidance, it was always limited (check np.concatenate in older versions). For NumPy, it's hstack that does the right thing here (perhaps by accident).
np.concat is not limited by this guidance, it was always limited (check np.concatenate in older versions)
This is exactly what I am saying: np.concatenate was always limited, and np.r_ was a way around the limitation.
definitely an improvement over r_ (all the *_ constructors are unreadable).
TBH, I fail to see how xp.concat((xp.expand_dims(x[0], 0), x)) is more readable than np.r_[x[0], x]. And it does not of course work for np.r_[0, x], which needs something like xp.concat((xp.zeros_like(x), x)) instead.
FWIW, I have no strong opinion either way. Although, if you allow 0-D the question is why not allow any broadcasting (except along the concatenated dimension) and it may be nice to have a NumPy PR to see what others think.
I could also see to allow optional broadcasting.
What has come up in NumPy before (I think Matt Haberland for example liked to have it), is a broadcast_arrays(*arrs, omit_axis=...). Doesn't quite make this particular use-case nice, but has some overlap (and makes writing the helper clean for N-D inputs).
Activity
[-]Allow scalars and 0D arrays in `concat`[/-][+]RFC: allow scalars and 0D arrays in `concat`[/+]vnmabus commentedon May 19, 2025
Why does this function not allow broadcasting? It seems like a more general solution isn't it?
kgryte commentedon May 19, 2025
The current guidance originates from NumPy (see https://numpy.org/doc/1.26/reference/generated/numpy.concatenate.html).
ev-br commentedon May 19, 2025
Yes, numpy's concatenate is limited by what is in this guidance. Numpy, however, has np.r_, which --- with all is sins --- allows extending arrays with scalars or 0D arrays. And this is what's missing in the array API land.
rgommers commentedon May 19, 2025
I think
np.concatis not limited by this guidance, it was always limited (checknp.concatenatein older versions). For NumPy, it'shstackthat does the right thing here (perhaps by accident).I'd say just go with the last line here. More verbose, but definitely an improvement over
r_(all the*_constructors are unreadable).This led me to rediscover gh-494, may be worth revisiting perhaps.
ev-br commentedon May 19, 2025
This is exactly what I am saying:
np.concatenatewas always limited, andnp.r_was a way around the limitation.TBH, I fail to see how
xp.concat((xp.expand_dims(x[0], 0), x))is more readable thannp.r_[x[0], x]. And it does not of course work fornp.r_[0, x], which needs something likexp.concat((xp.zeros_like(x), x))instead.This is almost
xpx.atleast_nd.rgommers commentedon May 19, 2025
Perhaps write a little helper function for SciPy then?
Then you can write it as
concat_1d(x[0], x, x[-1], xp=xp), which is about as good as it gets until there's a function in the standard that does this.ev-br commentedon May 19, 2025
Exactly. I've a scipy helper, and this issue is to gauge interest/possibility to make it work with
xp.concat(orxp.stack) and drop the helper.seberg commentedon May 29, 2025
FWIW, I have no strong opinion either way. Although, if you allow 0-D the question is why not allow any broadcasting (except along the concatenated dimension) and it may be nice to have a NumPy PR to see what others think.
I could also see to allow optional broadcasting.
What has come up in NumPy before (I think Matt Haberland for example liked to have it), is a
broadcast_arrays(*arrs, omit_axis=...). Doesn't quite make this particular use-case nice, but has some overlap (and makes writing the helper clean for N-D inputs).asmeurer commentedon May 29, 2025
Are there any upstream numpy issues about adding 0-D or broadcasting support to
np.concatenate?seberg commentedon May 29, 2025
numpy/numpy#28549 but I am not aware of old discussions (which coesn't mean they don't exist).
asmeurer commentedon May 29, 2025
The stackoverflow references on that issue certainly seem to imply that full broadcasting would be useful, not just support for 0-D concatenation.