0

Currently I have an array formatted like this: arr = [(1,1),(1,1)...(35,1),(35,1)])

I've written a code that calculates a 3rd value for each ordered pair in the array, one at a time. How can I create a new column that stores each calculated value as a new column in my array?

n1932
  • 1
  • 1
  • Is `arr` a NumPy array? Or a Python list? In other words, what does `type(arr)` return? – tsroten Jul 17 '15 at 17:54
  • Duplicate: [How to add column to numpy array](https://stackoverflow.com/questions/15815854/how-to-add-column-to-numpy-array). Take a look at [`numpy.concatenate`](http://docs.scipy.org/doc/numpy/reference/generated/numpy.concatenate.html). – tsroten Jul 17 '15 at 18:07
  • I already looked at that, but I wasn't sure if it worked with values that were being calculated in my code. – n1932 Jul 17 '15 at 18:18
  • Just create an array with your calculated values. Then concatenate the two arrays together. Make sure you concatenate using the correct axis. – tsroten Jul 17 '15 at 18:20

3 Answers3

1

Tuples are immutable, so you can't directly alter them. Fortunately, you can concatenate another tuple to them. Suppose you have an array:

arr = [(1, 2), (3, 4), (5, 6)]

and you want to append some integer to each tuple, let's say the index of the tuple in arr just for simplicity. That is, you want the final list to be:

arr = [(1, 2, 0), (3, 4, 1), (5, 6, 2)]

The following code will do just that:

arr = [item + (a.index(item),) for item in arr]

Note that the comma and parentheses in (a.index(item),) are crucial to form a tuple instead of an integer. (You can only concatenate tuples to other tuples.) So if you just want to add a number to a specific tuple, try:

arr[0] += (3,)

which will append a 3 to the end of the first element in arr. That will allow you to perform such concatenation in whatever loop is generating the third point, which you say happens one at a time. Happy coding!

dpwilson
  • 997
  • 9
  • 19
0

alternate solution, just replace the tuples as you go.

for i in range(len(arr)):
    arr[i] = (arr[i][0], arr[i][1], arr[i][0] * arr[i][1])
ate50eggs
  • 444
  • 3
  • 14
0

Array formated as arr = [(1,1),(1,1)...(35,1),(35,1)] can be confusing. It looks like an list of tuples. If that is what it is then, you need to use a list comprehension to make a new list:

arr1 = [(i,j, fun(i,j)) for i,j in arr]

e.g.

In [359]: arr=[(1,1),(1,2),(35,1),(35,2)]
In [360]: [(i[0],i[1], sum(i)) for i  in arr]
Out[360]: [(1, 1, 2), (1, 2, 3), (35, 1, 36), (35, 2, 37)]

But you say in a comment that arr is a numpy array.

In [361]: Arr=np.array(arr)    
In [362]: Arr
Out[362]: 
array([[ 1,  1],
       [ 1,  2],
       [35,  1],
       [35,  2]])

Same numbers, but it displays as a list of lists. An array that displays as a list of tuples is a structured array, with a different dtype.

Is the function something that can take this whole array, or must it be feed the values 2 by 2?

np.sum takes the whole array, and can return a 2d result:

In [366]: np.sum(Arr, axis=1, keepdims=True)
Out[366]: 
array([[ 2],
       [ 3],
       [36],
       [37]])

which can be easily concatenated onto Arr giving a new array:

In [370]: np.concatenate([Arr,np.sum(Arr, axis=1, keepdims=True)],axis=1)
Out[370]: 
array([[ 1,  1,  2],
       [ 1,  2,  3],
       [35,  1, 36],
       [35,  2, 37]])

On the other hand the Python sum just takes numbers. Arr can be used in a comprehension just like the list:

In [371]: [sum(i) for i  in Arr]
Out[371]: [2, 3, 36, 37]

To concatenate that onto the original, I need to turn it into a 2d 'vertical' array (as shown in Out[366])

In [376]: np.concatenate([Arr,np.array([sum(i) for i in Arr])[:,None]],axis=1)
Out[376]: 
array([[ 1,  1,  2],
       [ 1,  2,  3],
       [35,  1, 36],
       [35,  2, 37]])

append, vstack, hstack are all variations on concatenate. You could also construct a (4,3) array, and insert the values of Arr and new calculation.

hpaulj
  • 221,503
  • 14
  • 230
  • 353