1

I like to create a numpy array -- with a shape, say [2, 3], where each array element is a list. Yes, I know this isn't efficient, or even desirable, and all the good reasons for that -- but can it be done?

So I want a 2x3 array where each point is a length 2 vector, not a 2x3x2 array. Yes, really.

If I fudge it by making it ragged, it works:

>>> np.array([[0, 0], [0, 1], [0, 2], [1, 0], [9, 8], [2, 4, -1]], dtype=object).reshape([2, 3])
array([[list([0, 0]), list([0, 1]), list([0, 2])],
       [list([1, 0]), list([9, 8]), list([2, 4, -1])]], dtype=object)

but if numpy can make it fit cleanly, it does so, and so throws an error:

>>> np.array([[0, 0], [0, 1], [0, 2], [1, 0], [9, 8], [2, 4]], dtype=object).reshape([2, 3])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: cannot reshape array of size 12 into shape (2,3)

So putting aside your instincts that this is a silly thing to want to do (it is, and I know this), can I make the last example work somehow to create a shape 2x3 array where each element is a Python list of length 2, without numpy forcing it into 2x3x2?

1
  • Are you trying to keep it a 2x3 array of lists, rather than a 2x3x2 array? Did you try dtype=list? Commented Jan 19, 2023 at 9:38

3 Answers 3

3

First, you should create an object array with expected shape.

Then, use list to fill the array.

l = [[[0, 0], [0, 1], [0, 2]], [[1, 0], [9, 8], [2, 4]]]
arr = np.empty((2, 3), dtype=object)
arr[:] = l
Sign up to request clarification or add additional context in comments.

7 Comments

...huh. I remember that slice assignment not working when I tried it earlier (years ago), but it seems to work now. Either I'm remembering wrong, or they changed it since then.
This is beautiful
I'd like to share my opinion that I do find this question very relevant and deserving upvotes. The answers here prove that this is not trivial, while I think it can be useful in multiple cases and needs, e.g., when integrating Python code with a C application
@user2357112, perhaps you remember trying to assign an array. That will produce a broadcasting error. Assigning a list works.
@xpqz: If that's what you want, you can make a flat array, populate it, and then reshape it to whatever shape you want.
|
0

You can create an empty array and fill it with objects manually:

>>> a = np.empty((3,2), dtype=object)
>>> a
array([[None, None],
       [None, None],
       [None, None]], dtype=object)
>>> a[0,0] = [1,2,3]
>>> a
array([[list([1, 2, 3]), None],
       [None, None],
       [None, None]], dtype=object)

Comments

0

Anwering my own question, based on the fine answers provided by others, here's what I did:

l = [
    np.array([0, 0]), 
    np.array([0, 1]), 
    np.array([0, 2]), 
    np.array([1, 0]),
    np.array([9, 8]),
    np.array([2, 4])
]

arr = np.empty(len(l), dtype=object)
arr[:] = l
arr = arr.reshape((2, 3))

which gives

array([[array([0, 0]), array([0, 1]), array([0, 2])],
       [array([1, 0]), array([9, 8]), array([2, 4])]],  dtype=object)

which is exactly what I wanted. Thanks all!

1 Comment

It wasn't clear from your question that the objects you wanted to assign were numpy arrays rather than lists

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.