1

I find myself needing to create a numpy array of dtype="object" whose elements are themselves numpy arrays. I can manage to do this if the arrays are different lengths:

arr_of_arrs = np.empty((2,2), dtype=np.object)
arr_list = [np.arange(i) for i in range(4)]
arr_of_arrs.flat[:] = arr_list
print(arr_of_arrs)
array([[array([], dtype=int32), array([0])],
 [array([0, 1]), array([0, 1, 2])]], dtype=object)

But if they happen to be the same length, it doesn't work and I am not entirely sure how it is generating the values it gives me:

arr_list = [np.arange(2) for i in range(4)]
arr_of_arrs.flat[:] = arr_list
print(arr_of_arrs)
[[0 1]
[0 1]]

Is this even doable? numpy seems to try and coerce the data into "making sense" despite my best efforts to prevent it from doing so...

asked Feb 20, 2020 at 5:00
2
  • 1
    This kind of assignment works better if arr_of_arrs starts as a 1d array, e.g. np.empty(4, object). You can reshape it later if needed. flat is flattening and iterating both sides, which messes up this assignment. arr_of_arrays.ravel()[:]=... also works better. Commented Feb 20, 2020 at 5:19
  • @hpaulj That worked brilliantly! Make it an answer and I will upvote and accept. Commented Feb 20, 2020 at 5:22

1 Answer 1

1

If the array is 1d, the assignment works fine:

In [767]: arr = np.empty(4,object) 
In [768]: arr[:] = [np.arange(6) for _ in range(4)] 
In [769]: arr 
Out[769]: 
array([array([0, 1, 2, 3, 4, 5]), array([0, 1, 2, 3, 4, 5]),
 array([0, 1, 2, 3, 4, 5]), array([0, 1, 2, 3, 4, 5])], dtype=object)
In [770]: arr.reshape(2,2) 
Out[770]: 
array([[array([0, 1, 2, 3, 4, 5]), array([0, 1, 2, 3, 4, 5])],
 [array([0, 1, 2, 3, 4, 5]), array([0, 1, 2, 3, 4, 5])]],
 dtype=object)

We can also start with (2,2), but assign to ravel() (a view):

In [771]: arr = np.empty((2,2),object) 
In [772]: arr.ravel()[:] = [np.arange(6) for _ in range(4)] 
In [773]: arr 
Out[773]: 
array([[array([0, 1, 2, 3, 4, 5]), array([0, 1, 2, 3, 4, 5])],
 [array([0, 1, 2, 3, 4, 5]), array([0, 1, 2, 3, 4, 5])]],
 dtype=object)

flat apparently serializes the RHS:

In [774]: arr.flat = [np.arange(6) for _ in range(4)] 
In [775]: arr 
Out[775]: 
array([[0, 1],
 [2, 3]], dtype=object)

If the RHS list is nested right we can assign directly to the 2d array:

In [779]: alist = Out[770].tolist() 
In [780]: alist # list of lists of arrays 
Out[780]: 
[[array([0, 1, 2, 3, 4, 5]), array([0, 1, 2, 3, 4, 5])],
 [array([0, 1, 2, 3, 4, 5]), array([0, 1, 2, 3, 4, 5])]]
In [781]: arr = np.empty((2,2),object) 
In [782]: arr[:] = alist 
In [783]: arr 
Out[783]: 
array([[array([0, 1, 2, 3, 4, 5]), array([0, 1, 2, 3, 4, 5])],
 [array([0, 1, 2, 3, 4, 5]), array([0, 1, 2, 3, 4, 5])]],
 dtype=object)
answered Feb 20, 2020 at 21:01

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.