Let's say I have this array x:
x = array([1, 2, 3, 4, 5, 6, 7, 8])
x.shape = (8,1)
I want to reshape it to become
array([[1, 3, 5, 7],
[2, 4, 6, 8]])
this is a reshape(2, 4) on x but in the straight forward way:
y = x.reshape(2,4)
y becomes
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
and that's not what I want. Is there a way to transform the array in that specific way?
In[4]: x.reshape(4, 2).T
Out[4]:
array([[1, 3, 5, 7],
[2, 4, 6, 8]])
The easiest way to do this is to specify the orderargument in reshape function.
You need the Fortran order.
Side note: Matlab by default is using Fortran order but in python you need to specify that.
Use this:
x = np.array([1, 2, 3, 4, 5, 6, 7, 8])
y = x.reshape(2,4, order='F')
print(y)
#array([[1, 3, 5, 7],
# [2, 4, 6, 8]])
Another option is to use the option order='F' to your reshape-call like
res = numpy.reshape(my_array, (2,4), order='F')
https://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.reshape.html
Yes, you can do:
y = np.array([x[0::2], x[1::2]])
Related
Let's say I have a 2D array:
L = np.array([[1,2,3],
[4,5,6],
[7,8,9]])
I would like to make a 3D array from this, using a parameter N, such that (in this example, let's say N=4)
L2 = np.array([[[1,1,1,1],[2,2,2,2],[3,3,3,3]],
[[4,4,4,4],[5,5,5,5],[6,6,6,6]],
[[7,7,7,7],[8,8,8,8],[9,9,9,9]]])
Is there a nice way of doing this?
One option is to add another dimension, then repeat along the new dimension.
N = 4
out = L[..., None].repeat(N, axis=-1)
Output:
array([[[1, 1, 1, 1],
[2, 2, 2, 2],
[3, 3, 3, 3]],
[[4, 4, 4, 4],
[5, 5, 5, 5],
[6, 6, 6, 6]],
[[7, 7, 7, 7],
[8, 8, 8, 8],
[9, 9, 9, 9]]])
You can use a combination of swapaxes and broadcast_to:
N = 4
L2 = np.broadcast_to(L.swapaxes(0, 1), (N, *reversed(L.shape))).swapaxes(0, 2)
Output will be as desired.
Quite straightforward question, I have the following array:
x = np.array([1, 2, 3, 4, 5, 6, 7, 8])
I want to repeat this array over columns, having something like this:
array([[1, 1, 1],
[2, 2, 2],
[3, 3, 3],
[4, 4, 4],
[5, 5, 5],
[6, 6, 6],
[7, 7, 7],
[8, 8, 8]])
So, in order to do so I have been trying:
repeat_x = np.repeat(x, 3, axis = 1)
However, I get the following error:
AxisError: axis 1 is out of bounds for array of dimension 1
So, is there a way/trick to achieve my goal without having to use any sort of reshape?
Try this code:
np.array([x] * 3).T
Here 3 is the number of times you want to repeat those values
To do it purely in numpy without resorting back to python lists you need to use expand_dims followed by a transpose or use reshape to convert the vector into a matrix before using repeat.
x = np.array([1, 2, 3, 4, 5, 6, 7, 8])
# array([1, 2, 3, 4, 5, 6, 7, 8])
x = x.reshape(-1, 1)
# array([[1],
# [2],
# [3],
# [4],
# [5],
# [6],
# [7],
# [8]])
np.repeat(x.reshape(-1, 1), 3, 1)
# array([[1, 1, 1],
# [2, 2, 2],
# [3, 3, 3],
# [4, 4, 4],
# [5, 5, 5],
# [6, 6, 6],
# [7, 7, 7],
# [8, 8, 8]])
Using expand dims and a transpose will be like
np.repeat(np.expand_dims(x, 0).T, 3, 1)
Same result.
I have a matrix with dimention (2,5) and I have have a vector of values to be fill in that matrix. What is the best way. I can think of three methods but I have trouble using the np.empty & fill and np.full without loops
x=np.array(range(0,10))
mat=x.reshape(2,5)
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
mat=np.empty((2,5))
newMat=mat.fill(x) # Error: The x has to be scalar
mat=np.full((2,5),x) # Error: The x has to be scalar
full and fill are for setting all elements the same
In [557]: np.full((2,5),10)
Out[557]:
array([[10, 10, 10, 10, 10],
[10, 10, 10, 10, 10]])
Assigning an array works provided the shapes match (in the broadcasting sense):
In [558]: arr[...] = x.reshape(2,5) # make source the same shape as target
In [559]: arr
Out[559]:
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
In [560]: arr.flat = x # make target same shape as source
In [561]: arr
Out[561]:
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
arr.flat and arr.ravel() are equivalent. Well, not quite:
In [562]: arr.flat = x.reshape(2,5) # don't need the [:] with flat #wim
In [563]: arr
Out[563]:
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
In [564]: arr.ravel()[:] = x.reshape(2,5)
ValueError: could not broadcast input array from shape (2,5) into shape (10)
In [565]: arr.ravel()[:] = x.reshape(2,5).flat
flat works with any shape source, even ones that require replication
In [570]: arr.flat = [1,2,3]
In [571]: arr
Out[571]:
array([[1, 2, 3, 1, 2],
[3, 1, 2, 3, 1]])
More broadcasted inputs
In [572]: arr[...] = np.ones((2,1))
In [573]: arr
Out[573]:
array([[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]])
In [574]: arr[...] = np.arange(5)
In [575]: arr
Out[575]:
array([[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4]])
An example of the problem Eric mentioned. The ravel (or other reshape) of a transpose is (often) a copy. So writing to that does not modify the original.
In [578]: arr.T.ravel()[:]=10
In [579]: arr
Out[579]:
array([[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4]])
In [580]: arr.T.flat=10
In [581]: arr
Out[581]:
array([[10, 10, 10, 10, 10],
[10, 10, 10, 10, 10]])
ndarray.flat returns an object which can modify the contents of the array by direct assignment:
>>> array = np.empty((2,5), dtype=int)
>>> vals = range(10)
>>> array.flat = vals
>>> array
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
If that seems kind of magical to you, then read about the descriptor protocol.
Warning: assigning to flat does not raise exceptions for size mismatch. If there are not enough values on the right hand side of the assignment, the data will be rolled/repeated. If there are too many values, only the first few will be used.
If you want a 10x2 matrix of 5:
np.ones((10,2))*5
If you have a list of values and just want them in a particular shape:
datavalues = [1,2,3,4,5,6,7,8,9,10]
np.reshape(datavalues,(2,5))
array([[ 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10]])
I would like to generate a 2-by-N array in python for use with scipy.optimize.curve_fit.
I have a function of two independent variables stored as 1-D arrays, and the data in a 2-D array. curve_fit requires that the data be flattened, which is easy with data.ravel().
However, this is the hack I'm using to generate the 2xN array of ordinate values:
ordinate = np.array([[l,t] for l in length for t in time]).T
which works, but is slow. What's the (vectorized?) faster way?
If I got the question correctly, you are looking to form a 2D mesh out of the two independent variables stored as 1D arrays. So, for the same, you can use np.meshgrid -
time2D,length2D = np.meshgrid(time,length)
ordinate_vectorized = np.row_stack((length2D.ravel(),time2D.ravel()))
Sample run -
In [149]: time
Out[149]: array([7, 2, 1, 9, 6])
In [150]: length
Out[150]: array([3, 5])
In [151]: ordinate = np.array([[l,t] for l in length for t in time]).T
In [152]: ordinate
Out[152]:
array([[3, 3, 3, 3, 3, 5, 5, 5, 5, 5],
[7, 2, 1, 9, 6, 7, 2, 1, 9, 6]])
In [153]: time2D,length2D = np.meshgrid(time,length)
...: ordinate_vectorized = np.row_stack((length2D.ravel(),time2D.ravel()))
...:
In [154]: ordinate_vectorized
Out[154]:
array([[3, 3, 3, 3, 3, 5, 5, 5, 5, 5],
[7, 2, 1, 9, 6, 7, 2, 1, 9, 6]])
I have an array of a of shape (N,k) and another array b of shape (N,). I want to check if the ith value in b is contained in a[i]. If it is not present, I want to replace a[i,k] with b[i]. An example:
a = np.array([[1, 2, 2, 3, 4, 5],
[1, 2, 3, 3, 4, 5],
[1, 2, 3, 4, 4, 5],
[1, 2, 3, 4, 5, 5],
[1, 2, 3, 4, 5, 6]])
b = np.array([1,7,3,8,9])
The output array should look like this:
np.array([[1, 2, 2, 3, 4, 5],
[1, 2, 3, 3, 4, 7],
[1, 2, 3, 4, 4, 5],
[1, 2, 3, 4, 5, 8],
[1, 2, 3, 4, 5, 9]])
Writing loops over N seems to be very inefficient. In my dataset typically N is of the order of 10 million while k is about 50 to 100. Is there an efficient way to vectorize this using numpy functions?
The indices where to replace can be found doing:
s = a - b[:, None]
TOL = 1.e-6
ind = np.where(~(np.abs(s) <= TOL).any(axis=1))[0]
and thanks to NumPy's fancy indexing you can update your array in-place without for loops:
a[ind, :] = b[ind][:, None]