75

I need to accomplish the following task:

from:

a = array([[1,3,4],[1,2,3]...[1,2,1]])

(add one element to each row) to:

a = array([[1,3,4,x],[1,2,3,x]...[1,2,1,x]])

I have tried doing stuff like a[n] = array([1,3,4,x])

but numpy complained of shape mismatch. I tried iterating through a and appending element x to each item, but the changes are not reflected.

Any ideas on how I can accomplish this?

Salvador Dali
  • 214,103
  • 147
  • 703
  • 753
goh
  • 27,631
  • 28
  • 89
  • 151

7 Answers7

134

Appending data to an existing array is a natural thing to want to do for anyone with python experience. However, if you find yourself regularly appending to large arrays, you'll quickly discover that NumPy doesn't easily or efficiently do this the way a python list will. You'll find that every "append" action requires re-allocation of the array memory and short-term doubling of memory requirements. So, the more general solution to the problem is to try to allocate arrays to be as large as the final output of your algorithm. Then perform all your operations on sub-sets (slices) of that array. Array creation and destruction should ideally be minimized.

That said, It's often unavoidable and the functions that do this are:

for 2-D arrays:

for 3-D arrays (the above plus):

for N-D arrays:

Paul
  • 42,322
  • 15
  • 106
  • 123
13
import numpy as np
a = np.array([[1,3,4],[1,2,3],[1,2,1]])
b = np.array([10,20,30])
c = np.hstack((a, np.atleast_2d(b).T))

returns c:

array([[ 1,  3,  4, 10],
       [ 1,  2,  3, 20],
       [ 1,  2,  1, 30]])
eumiro
  • 207,213
  • 34
  • 299
  • 261
8

One way to do it (may not be the best) is to create another array with the new elements and do column_stack. i.e.

>>>a = array([[1,3,4],[1,2,3]...[1,2,1]])
[[1 3 4]
 [1 2 3]
 [1 2 1]]

>>>b = array([1,2,3])
>>>column_stack((a,b))
array([[1, 3, 4, 1],
       [1, 2, 3, 2],
       [1, 2, 1, 3]])
martijnn2008
  • 3,552
  • 5
  • 30
  • 40
chvck
  • 829
  • 10
  • 18
4

Appending a single scalar could be done a bit easier as already shown (and also without converting to float) by expanding the scalar to a python-list-type:

import numpy as np
a = np.array([[1,3,4],[1,2,3],[1,2,1]])
x = 10

b = np.hstack ((a, [[x]] * len (a) ))

returns b as:

array([[ 1,  3,  4, 10],
       [ 1,  2,  3, 10],
       [ 1,  2,  1, 10]])

Appending a row could be done by:

c = np.vstack ((a, [x] * len (a[0]) ))

returns c as:

array([[ 1,  3,  4],
       [ 1,  2,  3],
       [ 1,  2,  1],
       [10, 10, 10]])
Schauff
  • 41
  • 2
2

np.insert can also be used for the purpose

import numpy as np
a = np.array([[1, 3, 4],
              [1, 2, 3],
              [1, 2, 1]])
x = 5
index = 3 # the position for x to be inserted before
np.insert(a, index, x, axis=1)
array([[1, 3, 4, 5],
       [1, 2, 3, 5],
       [1, 2, 1, 5]])

index can also be a list/tuple

>>> index = [1, 1, 3] # equivalently (1, 1, 3)
>>> np.insert(a, index, x, axis=1)
array([[1, 5, 5, 3, 4, 5],
       [1, 5, 5, 2, 3, 5],
       [1, 5, 5, 2, 1, 5]])

or a slice

>>> index = slice(0, 3)
>>> np.insert(a, index, x, axis=1)
array([[5, 1, 5, 3, 5, 4],
       [5, 1, 5, 2, 5, 3],
       [5, 1, 5, 2, 5, 1]])
ayorgo
  • 2,803
  • 2
  • 25
  • 35
1

If x is just a single scalar value, you could try something like this to ensure the correct shape of the array that is being appended/concatenated to the rightmost column of a:

import numpy as np
a = np.array([[1,3,4],[1,2,3],[1,2,1]])
x = 10
b = np.hstack((a,x*np.ones((a.shape[0],1))))

returns b as:

array([[  1.,   3.,   4.,  10.],
       [  1.,   2.,   3.,  10.],
       [  1.,   2.,   1.,  10.]])
JoshAdel
  • 66,734
  • 27
  • 141
  • 140
-1
target = []

for line in a.tolist():
    new_line = line.append(X)
    target.append(new_line)

return array(target)
Marvin W
  • 3,423
  • 28
  • 16