BadProgrammer
BadProgrammer

Reputation: 371

Python declaring a numpy matrix of lists of lists

I would like to have a numpy matrix that looks like this [int, [[int,int]]] I receive an error that looks like this "ValueError: setting an array element with a sequence."

below is the declaration

def __init__(self):
    self.path=np.zeros((1, 2))

I attempt to assign a value to this in the line below

routes_traveled.path[0, 1]=[loc]

loc is a list and routes_traveled is the object

Upvotes: 0

Views: 2121

Answers (2)

hpaulj
hpaulj

Reputation: 231425

Do you want a higher dimensional array, say 3d, or do you really want a 2d array whose elements are Python lists. Real lists, not numpy arrays?

One way to put lists in to an array is to use dtype=object:

In [71]: routes=np.zeros((1,2),dtype=object)
In [72]: routes[0,1]=[1,2,3]
In [73]: routes[0,0]=[4,5]

In [74]: routes
Out[74]: array([[[4, 5], [1, 2, 3]]], dtype=object)

One term of this array is 2 element list, the other a 3 element list.

I could have created the same thing directly:

In [76]: np.array([[[4,5],[1,2,3]]]) 
Out[76]: array([[[4, 5], [1, 2, 3]]], dtype=object)

But if I'd given it 2 lists of the same length, I'd get a 3d array:

In [77]: routes1=np.array([[[4,5,6],[1,2,3]]])
Out[77]: 
array([[[4, 5, 6],
        [1, 2, 3]]])

I could index the last, routes1[0,1], and get an array: array([1, 2, 3]), where as routes[0,1] gives [1, 2, 3].

In this case you need to be clear where you talking about arrays, subarrays, and Python lists.


With dtype=object, the elements can be anything - lists, dictionaries, numbers, strings

In [84]: routes[0,0]=3
In [85]: routes
Out[85]: array([[3, [1, 2, 3]]], dtype=object)

Just be ware that such an array looses a lot of the functionality that a purely numeric array has. What the array actually contains is pointers to Python objects - just a slight generalization of Python lists.

Upvotes: 2

unutbu
unutbu

Reputation: 879919

Did you want to create an array of zeros with shape (1, 2)? In that case use np.zeros((1, 2)).

In [118]: np.zeros((1, 2))
Out[118]: array([[ 0.,  0.]])

In contrast, np.zeros(1, 2) raises TypeError:

In [117]: np.zeros(1, 2)
TypeError: data type not understood

because the second argument to np.zeros is supposed to be the dtype, and 2 is not a value dtype.


Or, to create a 1-dimensional array with a custom dtype consisting of an int and a pair of ints, you could use

In [120]: np.zeros((2,), dtype=[('x', 'i4'), ('y', '2i4')])
Out[120]: 
array([(0, [0, 0]), (0, [0, 0])], 
      dtype=[('x', '<i4'), ('y', '<i4', (2,))])

I wouldn't recommend this though. If the values are all ints, I think you would be better off with a simple ndarray with homogeneous integer dtype, perhaps of shape (nrows, 3):

In [121]: np.zeros((2, 3), dtype='<i4')
Out[121]: 
array([[0, 0, 0],
       [0, 0, 0]], dtype=int32)

Generally I find using an array with a simple dtype makes many operations from building the array to slicing and reshaping easier.

Upvotes: 1

Related Questions