I have a matrix X of size 30 * 30, and I want to put X automatically in each cell of the array Y (numpy array). I wrote the following Python code but I am not able to know how can I achieve what I want. More precisely, I want Y to be a matrix of size 99 * 1, where each element of Y is a matrix X.
import numpy as np
range_var = np.arange(10,100, 1)
Y = np.zeros(np.size(range_var))
for i in range_var:
X = np.random.rand(30,30)
Y[i] = X
Any help will be very appreciated!
This is kind of against the spirit of using NumPy (since it makes the numerical advantages vanish), but here you go:
Y = np.empty(100, dtype=object)
Y[...] = [np.ones((30, 30)) for _ in range(100)]
Replace np.ones
by whatever random function you actually deal with. Now, this produces a ragged array of array objects . There is no way to ensure (or encode in the shape or type) that the elements of Y
are of shape (30, 30)
; they might as well have random shapes. 1
For such scenarios, it is often better to just use a list
of arrays.
Notably, a very similar structure also works if you decide to have Y
as a 3D array:
Y2 = np.empty((100, 30, 30))
Y2[...] = [np.ones((30, 30)) for _ in range(100)]
although in that case you can directly write
Y3 = np.array([np.ones((30, 30)) for _ in range(100)])
and the result will automatically be concatenated. But both of these versions create unnecessary intermediate lists of arrays which could maybe be avoided with more information about the logic of your construction.
1 As outlined here , direct assignment of Y
do an np.array
with dtype=object
and equally shaped elements does not work by design.
You Might want to do like below:
import numpy as np
range_var = np.arange(10,100, 1)
Z = np.zeros(np.size(range_var))
Y = [[]] * len(Z)
for i in range(len(Y)):
X = np.random.rand(30,30)
Y[i] = X
print(Y[0])
the output of the fist element of Y
is something like below:
[[8.71768142e-03 1.95842121e-01 3.48960380e-01 4.82051977e-01 2.82854636e-01 5.16650577e-01 6.99694637e-01 9.74657948e-01 1.74005728e-01 7.87224769e-01 8.45505123e-01 6.06426391e-01 6.28956958e-01 7.61095262e-01 4.83874602e-01 7.19727490e-01 1.12914684e-01 9.57578821e-01 4.15939585e-01 4.32561004e-01 5.23185891e-01 8.94867683e-01 4.03805754e-01 3.31016882e-01 6.15462553e-01 6.05025939e-01 4.93821722e-01 4.57816110e-01 2.29621863e-01 5.50679914e-01] [1.89572414e-01 3.18888371e-01 2.45477287e-01 5.84301398e-01 7.19882461e-01 3.76206859e-01 3.36516800e-01 6.62839901e-01 5.34286198e-01 6.43281618e-01 5.04704960e-01 4.11075044e-01 3.70793810e-01 2.09171377e-01 8.26894090e-01 4.88145383e-01 9.76859585e-01 5.66362393e-01 5.00326056e-02 3.03405329e-01 3.47386966e-01 3.38509244e-01 2.44756099e-01 7.26830086e-01 3.53031198e-01 5.71449664e-01 3.67615943e-01 8.77292061e-01 4.60977301e-01 2.84626276e-01]...etc]
I my comment I asked you to display the error produced by your code:
In [200]: range_var = np.arange(10,100, 1)
...: Y = np.zeros(np.size(range_var))
...:
...: for i in range_var:
...: X = np.random.rand(30,30)
...: Y[i] = X
...:
TypeError: only size-1 arrays can be converted to Python scalars
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<ipython-input-200-d3febad37a25>", line 6, in <module>
Y[i] = X
ValueError: setting an array element with a sequence.
Look at the elements of this code:
In [201]: Y.shape # a 90 element array, by definition
Out[201]: (90,)
In [202]: Y[i] # one element of this array
Out[202]: 0.0
In [203]: X # a (30,30) shaped array
Out[203]:
array([[0.7509964 , 0.5079236 , 0.21115 , 0.01971662, 0.89276404,
....
It says you can't put many items (sequence) into a slot that accepts only one number.
One answer suggests creating Y
to be object dtype, which can then accept arrays as elements. But an object dtype array is just a glorified (or bastardized) list.
If all the X
are the same size, you can create a 3d array that will accept those subarrays.
Y = np.zeros((N,30,30))
If the X
differ in shape, then you have to go the object
route, though I still think a list is better.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.