Reputation: 551
I'm trying to store multiple 2D arrays (STAR) inside of a larger 3D array (called STACK) that can continue to grow in size. I need STACK to be a global parameter that can be accessed by multiple functions at any time. To do this I tried using numpy.dstack()
So far this is what my code looks like:
box_size = np.shape(star)[0]
# The 2D array I'm trying to add to the STACK
STAR = [[1, 1, 1, 1, 1],\
[1, 1, 2, 1, 1],\
[1, 2, 3, 2, 1],\
[1, 1, 2, 1, 1],\
[1, 1, 1, 1, 1,]]
# Initialize STACK to be an empty array the same size as STAR
STACK = np.zeros((2*(box_size/2)+1,2*(box_size/2)+1))
# A function that appends STAR to STACK
def add_Star(STAR):
np.dstack((STACK,STAR))
# Call the function
add_Star(STAR)
However when I try to print the updated STACK, I get
[[ 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0.]]
I don't know if I'm missing something obvious or completely misusing the function.
To be clear, I'd like STACK to be a memory of every STAR I add to it. That is, I'd like each STAR to be accessible in the STACK if I need, to say, remove it later. In practice every STAR is going to be different, so simply adding STACK to STAR isn't going to work.
Upvotes: 0
Views: 2135
Reputation: 231385
Let's streamline your action a bit, to better understand what is going on
In [125]: n=5
Make star
an array, a 5x5 one using your values
In [126]: star=np.array([[1, 1, 1, 1, 1],\ # don't need the \
[1, 1, 2, 1, 1],\
[1, 2, 3, 2, 1],\
[1, 1, 2, 1, 1],\
[1, 1, 1, 1, 1,]])
In [127]: star
Out[127]:
array([[1, 1, 1, 1, 1],
[1, 1, 2, 1, 1],
[1, 2, 3, 2, 1],
[1, 1, 2, 1, 1],
[1, 1, 1, 1, 1]])
initial stack
to zeros of the same size. This is not the same as an 'empty' array.
In [128]: stack=np.zeros((5,5))
In [130]: newstack=np.dstack((stack,star))
In [131]: newstack.shape
Out[131]: (5, 5, 2)
dstack
is not like the list append. It makes a new array. Note the shape - 3d.
In [132]: newstack
Out[132]:
array([[[ 0., 1.],
[ 0., 1.],
[ 0., 1.],
[ 0., 1.],
[ 0., 1.]],
....
Note, it has the zeros plus the star values.
In [133]: newstack=np.dstack((newstack,star))
In [134]: newstack.shape
Out[134]: (5, 5, 3)
Do you really want to do this?
Here's a better way of building a 3d array incrementally:
In [135]: alist=[]
In [136]: alist.append(star)
In [137]: alist.append(star)
In [138]: alist
Out[138]:
[array([[1, 1, 1, 1, 1],
[1, 1, 2, 1, 1],
[1, 2, 3, 2, 1],
[1, 1, 2, 1, 1],
[1, 1, 1, 1, 1]]), array([[1, 1, 1, 1, 1],
[1, 1, 2, 1, 1],
[1, 2, 3, 2, 1],
[1, 1, 2, 1, 1],
[1, 1, 1, 1, 1]])]
In [139]: np.array(alist)
Out[139]:
array([[[1, 1, 1, 1, 1],
[1, 1, 2, 1, 1],
[1, 2, 3, 2, 1],
[1, 1, 2, 1, 1],
[1, 1, 1, 1, 1]],
...)
In [140]: _.shape
Out[140]: (2, 5, 5)
Note that np.array
joins the components along a new axis, at the front. This is the better place for doing that in numpy
.
You mention removing a 'star' later; that will be easier if you leave it in the list form. The 3d array form is useful if you need to do calculations across 'star', but otherwise might not be needed.
Or if you know how many star
you will have, you can initial the stack
to the right size, and assign values:
In [146]: stack=np.zeros((2,5,5),dtype=int)
In [147]: stack[0,:,:] = star
In [148]: stack[1,:,:] = star*2
In [149]: stack
Out[149]:
array([[[1, 1, 1, 1, 1],
[1, 1, 2, 1, 1],
[1, 2, 3, 2, 1],
[1, 1, 2, 1, 1],
[1, 1, 1, 1, 1]],
[[2, 2, 2, 2, 2],
[2, 2, 4, 2, 2],
[2, 4, 6, 4, 2],
[2, 2, 4, 2, 2],
[2, 2, 2, 2, 2]]])
This too is better than repeatedly using dstack
(or some other concatenation).
Upvotes: 0
Reputation: 423
There seem to be a few confusions here.
First, the following code should do what you want it to, with as few changes as possible:
# The 2D array I'm trying to add to the STACK
STAR = [[1, 1, 1, 1, 1],\
[1, 1, 2, 1, 1],\
[1, 2, 3, 2, 1],\
[1, 1, 2, 1, 1],\
[1, 1, 1, 1, 1,]]
STAR = np.asarray(STAR)
# Initialize STACK to be an empty array the same size as STAR
STACK = np.zeros(STAR.shape, np.float_)
# A function that appends STAR to STACK
def add_Star(star):
out = np.dstack((STACK,star))
return out
# Call the function
STACK = add_Star(STAR)
Now let's break down why. Most importantly, the variables in your function e.g. the star
in
def add_Star(star)
don't have to be the same names as variables elsewhere in your code (and in fact shouldn't, because it's confusing). Only in the function call
STACK = add_Star(STAR)
do you need to feed the function some variable defined elsewhere.
You'll notice that I also added return to the function, because I interpreted your question as wanting to be able to run add_Star repeatedly, and each time to output an expanded STACK.
Also, an easy way to see the dimensions of any given array is
array.shape
You'll see I used that to define the shape of STACK, rather than going through the extra step of defining a box_size.
Finally, STAR as you had it defined was not in array form. When using numpy, it's easy to just use np.asarray to get a list like you had into array format.
Upvotes: 1
Reputation: 769
You could do this using lists by using the append
function:
STAR_1 = [[1, 1, 1, 1, 1],\
[1, 1, 2, 1, 1],\
[1, 2, 3, 2, 1],\
[1, 1, 2, 1, 1],\
[1, 1, 1, 1, 1,]]
STACK = [STAR_1]
STAR_2 = [[2, 2, 2, 2, 2],\
[1, 1, 2, 1, 1],\
[1, 2, 3, 2, 1],\
[1, 1, 2, 1, 1],\
[1, 1, 1, 1, 1,]]
STACK.append(STAR_2)
print(STACK)
This will print:
[[[1, 1, 1, 1, 1],
[1, 1, 2, 1, 1],
[1, 2, 3, 2, 1],
[1, 1, 2, 1, 1],
[1, 1, 1, 1, 1]],
[[2, 2, 2, 2, 2],
[1, 1, 2, 1, 1],
[1, 2, 3, 2, 1],
[1, 1, 2, 1, 1],
[1, 1, 1, 1, 1]]]
Upvotes: 0