I'm creating code in Python and I need to perform some operations with arrays. One of them consists of storing an array in a specific position of another array. I tried this:
import numpy as np
b = np.zeros([2, 2])
a = np.array([[0, 1], [1, 2]])
b[0, 0] = a
print(b)
But I got the following error:
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 "C:/Users/Juan Vera/AppData/Roaming/JetBrains/PyCharmCE2021.2/scratches/scratch_11.py", line 6, in <module>
b[0, 0] = a
ValueError: setting an array element with a sequence.
How can I fix this error?
CodePudding user response:
The default data-type of np.zeros
is np.float64
. Meaning, the array b
expects its entries to be 64-bit floating point numbers.
When you pass the line b[0,0] = a
you get the error that you are trying to squeeze a sequence into an array element.
If you change the data-type of your array b
to object
, then b
expects it's elements to be any old object
. So you'd have no problems with b[0, 1]
being a number and b[0, 0]
being an array. Like so:
import numpy as np
b = np.zeros((2, 2), dtype=object)
a = np.array([[0, 1], [1, 2]])
b[0, 0] = a
If this seems overly stuffy/detailed, note that that is one of the tradeoffs with numpy. Numpy provides speed upgrades at the cost of being "closer to the metal". Type specification is one of those upgrades.
Also, you may just be playing around, but in general, I would very much advise someone not to use numpy arrays like this in practice (as there's likely a better data structure to fit your needs).
Edit:
If your intent was to broadcast a
into the 2x2
submatrix starting at position (0,0)
in b
, then this example might be helpful:
import numpy as np
b = np.zeros((4, 4))
a = np.array([[0, 1],[1,2]])
c = np.array([[3, 4],[5,6]])
b[0:0 a.shape[0], 0:0 a.shape[1]] = a
b[2:2 c.shape[0], 2:2 c.shape[1]] = c
print(b)
# [[ 0. 1. 0. 0.]
# [ 1. 2. 0. 0.]
# [ 0. 0. 3. 4.]
# [ 0. 0. 5. 6.]]
This way of operating on numpy arrays (where the array storage structure itself doesn't change, just the values of the elements) is perfectly fine. This is because numpy knows a priori how much space in memory to assign for the array when the datatype is a numerical one like float64
or int
. In contrast, when working with a numpy with dtype object
, the array is constantly being written and rewritten in memory -- an expensive process that undoes a large benefit of working with numpy (namely, speed improvements in array operations).
CodePudding user response:
Using just the title "Store an array into a specific position of another array" the following code does this:
a = ['x', 'y']
b = [1, 2, 3]
b.insert(0, a)
print(b)
# Outputs
# [['x', 'y'], 1, 2, 3]
Can control the index like so:
b.insert(1, a)
# Outputs
# [1, ['x', 'y'], 2, 3]
CodePudding user response:
It depends on what you want to achieve. If you want to overwrite the corresponding "patch" of the array b
, then use slicing:
b[0:2, 0:2] = a # or b[:, :] if a and b has the same shapes
print(b)
# [[0. 1.]
# [1. 2.]]
On the other hand, although rarely so, if you want to set the [0, 0]
th element as the array a
, then try (note dtype=object
):
import numpy as np
b = np.zeros([2, 2], dtype=object)
a = np.array([[0, 1], [1, 2]])
b[0, 0] = a
print(b)
# [[array([[0, 1],
# [1, 2]]) 0]
# [0 0]]
In this way b[0, 0]
is now an array, b[0, 1] == 0
(a number), and so on. Again, this is rarely what you want, and in general avoided.