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...

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)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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.