Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create empty matrix Python

I simply want to create an empty 10*3*2 array with Python.

I first thought of these one, but this is not working:

parameters = [ [ [] * 2 ]*3 ] * 10

this gives me a vector of ten vectors, with three [] elements in it:

[[[], [], []], [[], [], []], [[], [], []], [[], [], []], [[], [], []], 
[[], [], []], [[], [], []], [[], [], []], [[], [], []], [[], [], []]]

that is , if I want to access parameters[0][0][1] I am out of bounds, whereas I want a dimension 2 for the innermost vectors along the third dimension.

then I thought of this

[ [ [[] * 2] ]*3 ] * 10

I was thinking that [[] * 2] would now bring me the thing I want, an innermost two elements vector. I obtain

[[[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]], 
[[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]], 
[[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]]]

So, how to do it, or how to escape this initialization?

Kd rgds.

like image 918
kiriloff Avatar asked Nov 12 '12 16:11

kiriloff


3 Answers

I would recommend you use Numpy for this kind of stuff. It makes accessing columns or rows much easier. For your use case you'd do

import numpy as np

matrix = np.zeros((2,3,10))
second_col = matrix[:,1,:]

Numpy will also take better care of your data, and it implements a lot of the matrix algebra in Fortran or C so it's going to be a lot faster in the (possible) future when you're doing matrix multiplication and the likes.

like image 187
Matti Lyra Avatar answered Oct 16 '22 11:10

Matti Lyra


First of all, you should insert something into the innermost list (like None). Secondly, when you use the multiplication in the outermost list it replicates references to the inner list, so when you change one element, you will also change this element in all the other lists:

>> parameters = [ [ [None] * 2 ]*3 ] * 10
>> print parameters
[[[None, None], [None, None], [None, None]],
 [[None, None], [None, None], [None, None]],
 [[None, None], [None, None], [None, None]],
 [[None, None], [None, None], [None, None]],
 [[None, None], [None, None], [None, None]],
 [[None, None], [None, None], [None, None]],
 [[None, None], [None, None], [None, None]],
 [[None, None], [None, None], [None, None]],
 [[None, None], [None, None], [None, None]],
 [[None, None], [None, None], [None, None]]]
>> parameters[0][0][1]=1
>> print parameters 
[[[None, 1], [None, 1], [None, 1]], [[None, 1], [None, 1], [None, 1]], [[None, 1], [None, 1], [None, 1]], [[None, 1], [None, 1], [None, 1]], [[None, 1], [None, 1], [None, 1]], [[None, 1], [None, 1], [None, 1]], [[None, 1], [None, 1], [None, 1]], [[None, 1], [None, 1], [None, 1]], [[None, 1], [None, 1], [None, 1]], [[None, 1], [None, 1], [None, 1]]]

Therefore, you should rather use list comprehensions:

>> parameters=[[[None for i in range(2)] for j in range(3)] for k in range(10)]

However, I would recommend to use numpy as suggested in one of the other answers.

like image 37
btel Avatar answered Oct 16 '22 10:10

btel


Here's one of the problems with what you're doing.

Let's say you're creating an array, like so:

>>> l = [ [ [[] * 2] ]*3 ] * 10
>>> l
[[[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]], [[[]], [[]], [[]]]]

Seems okay so far. Let's set something in the array.

>>> l[0][0][0] = 2
>>> l
[[[2], [2], [2]], [[2], [2], [2]], [[2], [2], [2]], [[2], [2], [2]], [[2], [2], [2]], [[2], [2], [2]], [[2], [2], [2]], [[2], [2], [2]], [[2], [2], [2]], [[2], [2], [2]]]

Woah! We set 1 item in it, but it changed everything! How'd that happen?

Well, it appears that we have 60 list objects. However, we actually have 60 references to one list object. Change one, change them all.

TL;DR: Don't use the multiply operator on a list of lists.

like image 7
Nick ODell Avatar answered Oct 16 '22 12:10

Nick ODell