简体   繁体   中英

How can I put an array into a matrix elements automatically in Python?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM