简体   繁体   中英

Operator + to add a tuple to another tuple stored inside a multidimensional array of tuples

I recently found out how to use tuples thanks to great contributions from SO users(see here ). However I encounter the problem that I can't add a tuple to another tuple stored inside an array of tuples. For instance if I define:

arrtup=empty((2,2),dtype=('int,int'))
arrtup[0,1]=(3,4)

Then if I try to add another tuple to the existing tupe to come up with a multidimensional index:

arrtup[0,1]+(4,4)

I obtain this error:

TypeError: unsupported operand type(s) for +: 'numpy.void' and 'tuple'

Instead of the expected (3,4,4,4) tuple, which I can obtain by:

(3,4)+(4,4)

Any ideas? Thanks!

You are mixing different concepts, I'm afraid.

Your arrtup array is not an array of tuples, it's a structured ndarray , that is, an array of elements that look like tuples but in fact are records ( numpy.void objects, to be exact). In your case, you defined these records to consist in 2 integers. Internally, NumPy creates your array as a 2x2 array of blocks, each block taking a given space defined by your dtype : here, a block consists of 2 consecutive blocks of size int (that is, each sub-block takes the space an int takes on your machine).

When you retrieve an element with arrtup[0,1] , you get the corresponding block. Because this block is structured as two-subblocks, NumPy returns a numpy.void (the generic object representing structured blocks), which has the same dtype as your array.

Because you set the size of those blocks at the creation of the array, you're no longer able to modify it. That means that you cannot transform your 2-int records into 4-int ones as you want.

However, you can transform you structured array into an array of objects :

new_arr = arrtup.astype(object)

Lo and behold, your elements are no longer np.void but tuples, that you can modify as you want:

new_arr[0,1] = (3,4) # That's a tuple
new_arr[0,1] += (4,4) # Adding another tuple to the element

Your new_arr is a different beast from your arrtup : it has the same size, true, but it's no longer a structured array, it's an array of objects, as illustrated by

>>> new_arr.dtype
dtype("object")

In practice, the memory layout is quite different between arrtup and newarr . newarr doesn't have the same constraints as arrtup , as the individual elements can have different sizes, but object arrays are not as efficient as structured arrays.

The traceback is pretty clear here. arrtup[0,1] is not a tuple. It's of type `numpy.void'.

You can convert it to a tuple quite easily however:

tuple(arrtup[0,1])

which can be concatenated with other tuples:

tuple(arrtup[0,1]) + (4,4)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM