3

I can index a 2d numpy array with a tuple or even a list of tuples

a = numpy.array([[1,2],[3,4]])
i = [(0,1),(1,0)] # edit: bad example, should have taken [(0,1),(0,1)]
print a[i[0]], a[i]

(Gives 2 [2 3])

However, I can not manipulate the tuples with vector arithmetic, i.e.

k = i[0]+i[1]

does not give the desired (1,1) but concatenates.

On the other hand using numpy arrays for the indices, the arithmetic works, but the indexing does not work.

i = numpy.array(i)
k = i[0]+i[1]      # ok
print a[k]

gives the array [[3 4], [3 4]] instead of the desired 4.

Is there a way to do vector arithmetic on the indices but also be able to index a numpy array with them (without deriving a class from tuple and overloading all the operators)?

This question looked promising at first but I could not figure out if I can apply it to my situation.

Edit (comment on accepted answer):

... and working on arrays of indices then works as well using map

arr = numpy.array([[1,2,3],[4,5,6],[7,8,9]])
ids = numpy.array([(0,1),(1,0)])
ids += (0,1) # shift all indices by 1 column
print arr[map(tuple,ids.T)]

(confusing to me why I need the transpose, though. Would have run into this problem above as well, and was just fortunate with [(0,1),(0,1)])

Community
  • 1
  • 1
Kyss Tao
  • 521
  • 4
  • 13

3 Answers3

2

Yes. Convert the NumPy array to a tuple when you need to index:

a[tuple(k)]

Test:

>>> a = numpy.array([[1,2],[3,4]])
>>> i = numpy.array([(0,1),(1,0)])
>>> k = i[0] + i[1]
>>> a[tuple(k)]
4
YXD
  • 31,741
  • 15
  • 75
  • 115
  • +1 ah simple, should have thought of this myself! That would give may `tuple` in my code, but I will use it for now and if it get too many `tuple` I can still derive a class of my own in the end – Kyss Tao Mar 15 '12 at 14:48
1

I believe the most straightforward way to do this would be to create a subclass of tuple and redefine its __add__ operator to do what you want. Here is how to do that: Python element-wise tuple operations like sum

Community
  • 1
  • 1
Brendan Wood
  • 6,220
  • 3
  • 30
  • 28
  • see my question (in the brackets before the question mark). Adding was just an example I'd need `__add__` `__sub__` `__mul__` `__rmul__` `__div__` and each for scalar/vector and vector/vector. Maybe such a class would be a nice extension for a future version of Python. – Kyss Tao Mar 15 '12 at 14:43
0

try the following, it works for me:

import numpy

def functioncarla(a,b):
    return a+b

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

#k = i[0]+i[1]
aux = map(functioncarla, i[0], i[1])
k = tuple(aux)
print 'k = ', k

print 'a[k] = ', a[k]
carla
  • 2,181
  • 19
  • 26