Reputation: 59
I have an array:
X ndarray 180x360
The following does not work
X = numpy.append(X, X[:,0], 1)
because X[:,0]
has the wrong dimensions.
Is not this weird?
This way around the problem seems a bit dirty:
X = numpy.append(X, numpy.array(X[:,0],ndmin=2).T, axis=1)
In MATLAB one could just write: X(:,361) = X(:,1)
!!!
I came to realize that this works, too:
X = numpy.insert(X, 361, X[:,0], axis=1)
but why append does not work similarly?
Thank you serpents
Upvotes: 0
Views: 2679
Reputation: 231335
A key difference is that in MATLAB everything has at least 2 dimensions.
>> size(x(:,1))
ans =
2 1
and as you note, it allows indexing 'beyond-the-end' - way beyond
>> x(:,10)=x(:,1)
x =
1 2 3 1 0 0 0 0 0 1
4 5 6 4 0 0 0 0 0 4
But in numpy
indexing reduces the dimensions, without the 2d floor:
In [1675]: x = np.ones((3,4),int)
In [1676]: x.shape
Out[1676]: (3, 4)
In [1677]: x[:,0].shape
Out[1677]: (3,)
That means that if I want to replicate a column I need to make sure it is still a column in the concatenate
. There are numerous ways of doing that.
x[:,0][:,None]
- use of np.newaxis
(alias None
) is a nice general purpose method. x[:,[0]]
, x[:,0:1]
, x[:,0].reshape(-1,1)
also have their place.
append
is just concatenate
that replaces the list of arguments with 2. It's a confusing imitation of the list append. It is written Python so you can read it (as experienced MATLAB coders do).
insert
is a more complicated function (also in Python). Adding at the end it does something like:
In [1687]: x.shape
Out[1687]: (3, 4)
In [1688]: res=np.empty((3,5),int)
In [1689]: res[:,:4] = x
In [1690]: res[:,-1] = x[:,0]
That last assignment works because both sides have the same shape (technically they just have to be broadcastable shapes). So insert
doesn't tell us anything about what should or should not work in more basic operations like concatenate
.
Upvotes: 0
Reputation: 152587
The reason is that indexing with one integer removes that axis:
>>> X[:, 0].shape
(180,)
That's a one dimensional array, but if you index by giving a start and stop you keep the axis:
>>> X[:, 0:1].shape
(180, 1)
which could be correctly appended to your array:
>>> np.append(a, a[:, 0:1], 1)
array([....])
But all this aside if you find yourself appending
and concatenating
lots of arrays be warned: These are extremly inefficient. Most of the time it's better to find another way of doing this, for example creating a bigger array in the beginning and then just setting the rows/columns by slicing:
X = np.zeros((180, 361))
X[:, 360] = X[:, 0] # much more efficient than appending or inserting
Upvotes: 1
Reputation: 5019
You can create a new axis on X[:,0]
:
np.append(X, X[:,0,None], axis=1)
I think the reason why you have to match array shapes is that numpy.append
is implemented using concatenate
.
Upvotes: 0