I'm trying to append one numpy array to another numpy array, like this:

import numpy as np
meanings = 2
signals = 4

def new_agent(agent_type, context_size):
    if agent_type == 'random':
        comm_system = np.random.random_integers(0, 1, (meanings, signals))
    if agent_type == 'blank':
        comm_system = np.zeros((meanings, signals), int)
    score_list = np.array([0., 0., 0., 0.])
    np.append(comm_system, score_list)
    np.append(comm_system, context_size)
    return comm_system

if I now call:

random_agent = new_agent('random', 5)

I expect to get something like:

[[0 1 0 0]
[1 1 0 1]
[0. 0. 0. 0.]
5]

But instead I get only:

[[0 1 0 0]
[1 1 0 1]]

So the score_list and the context_size don't get appended. And the same holds for when I call new_agent() with 'blank'.

Thanks!

share|improve this question

numpy.append() returns a new array containing the data from its inputs together. It does not modify the inputs themselves, and there would be no way for it to do so. This is because arrays in NumPy are generally not resizable.

Try changing your code to capture the value returned from append(), which will be the array you want.

share|improve this answer
    
Aah, I see. Thanks! – Marieke_W Nov 20 '13 at 11:47

@John is correct about how to use the return value from numpy.append because it doesn't modify the original array. However, there's a problem with your expected output:

[[0 1 0 0]
 [1 1 0 1]
 [0. 0. 0. 0.]
 5]

is not a possible numpy array because of two reasons: one is that some elements are integers and some are floats, but a numpy array's dtype must be uniform; the other is that each row is not the same length, but numpy arrays must have uniform (rectangular) shape.

I think what you might rather do is to just return all three things:

  • comm_system as an array of ints,
  • score_list as an array of floats,
  • and context_size as an int (not an array).

You can do that with a tuple:

def new_agent(agent_type, context_size):
    if agent_type == 'random':
        comm_system = np.random.random_integers(0, 1, (meanings, signals))
    if agent_type == 'blank':
        comm_system = np.zeros((meanings, signals), int)
    score_list = np.zeros(signals)  #This is different too! No need to type out the 0, 0, ...
    # now just return all three:
    return comm_system, score_list, context_size

Then you can "unpack" the tuple like so:

random_agent, scores, size = new_agent('random', 5)

Or just keep them all in one tuple:

random_agent_info = new_agent('random', 5)

And you'll have

In [331]: random_agent, scores, size = new_agent('random', 5)

In [332]: random_agent
Out[332]: 
array([[0, 1, 1, 0],
       [0, 1, 0, 1]])

In [333]: scores
Out[333]: array([ 0.,  0.,  0.,  0.])

In [334]: size
Out[334]: 5

In [336]: random_agent_info
Out[336]: 
(array([[1, 1, 0, 1],
        [0, 1, 0, 0]]),
 array([ 0.,  0.,  0.,  0.]),
 5)

In [337]: random_agent_info[0]
Out[337]: 
array([[1, 1, 0, 1],
       [0, 1, 0, 0]])

In [338]: random_agent_info[1]
Out[338]: array([ 0.,  0.,  0.,  0.])

In [339]: random_agent_info[2]
Out[339]: 5

If you do want to have the comm_system and score_list to be one (3,2) array, you can do that with:

def new_agent(agent_type, context_size):
    ...
    return np.vstack([comm_system, score_list]), context_size

Then you'll get one array and one int:

In [341]: random_agent, size = new_agent('random', 5)

In [342]: random_agent
Out[342]: 
array([[ 1.,  0.,  1.,  1.],
       [ 1.,  0.,  1.,  0.],
       [ 0.,  0.,  0.,  0.]])

In [343]: size
Out[343]: 5
share|improve this answer

You can use hstack and vstack to concatenate arrays:

>>> from numpy import array, hstack, vstack
>>> a = array([1, 2, 3])
>>> b = array([4, 5, 6])
>>> hstack([a, b])
array([1, 2, 3, 4, 5, 6])
>>> vstack([a, b])
array([[1, 2, 3],
       [4, 5, 6]])
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.