3

I would like to take the information from some fields and just write them into another variable using a list.

import numpy as np
var1 = np.array([(1,2,3,4),(11,22,33,44),(111,222,333,444)], dtype=([('field1', 'int32'),('field2','int32'),('field3','int32'),('field4','int32')]))
var2 = np.empty((1), dtype = ([('field1', 'int32'),('field2','int32'),('field5','int32'),('field6','int32')]))
myList = ['field1', 'field2']

I want to write the values from the 1st and 2nd fields and 1st row to var2. I try the following:

var2[(myList)] = var1[(myList)][0]

But I get the following error:

IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices

What I want to achieve the same if I perform:

var2['field1'] = var1['field1'][0]
var2['field2'] = var1['field2'][0]

How could I do this in order to able to perform this with higher lists avoiding a for loop over the list?

Anand S Kumar
  • 88,551
  • 18
  • 188
  • 176
Xesc
  • 31
  • 2

1 Answers1

2

A list of fields works for fetching a subset of the fields

In [139]: var1[myList]
Out[139]: 
array([(1, 2), (11, 22), (111, 222)], 
      dtype=[('field1', '<i4'), ('field2', '<i4')])

but not when used on the left side as a 'setter' (this may be an area of development).

In [138]: var2[myList]= var1[myList]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-138-570d16e71a2e> in <module>()
----> 1 var2[myList]= var1[myList]

IndexError: unsupported iterator index

So you need to iterate on the fields.

for name in myList:
    var2[name] = var1[name][0]     

Iterating on field names is common practice in structured array code (as in np.rec functions). Typically a structured array will have many elements ('rows') but a few fields ('columns'), so iteration over fields is not expensive.


In this case, all fields of var2 are the same int dtype. So I can perform the assignment on the corresponding 2d view

In [160]: var2.view(int)[:2] = var1[myList][0].tolist()

var2 data buffer is all ints, so it can be viewed either as fields or a regular array (2d or 1).

var2.view(int)[:2] = var1[myList][0] assigns var1['field1'][0] to both items of var2. So I have to make it into a list or tuple.

Alternatively I can view var1 as well. With this I found I need to reshape as well. The view produces a 1d array view of the buffer.

var2.view(int)[:2]=var1.view(int).reshape((3,4))[0,:2]

Multifield assignment is under development, but I don't think it is in the official release yet. https://github.com/numpy/numpy/pull/6053


var1.view(int).reshape((3,4))  # or 
var1.view(int).reshape((-1,4))

can also be expressed as:

var1.view((int,4))

(the compound view is more compact, though not any faster).

hpaulj
  • 221,503
  • 14
  • 230
  • 353
  • I already tired this way, but I thought that it would be a more efficient way... Thank you anyway! – Xesc Oct 13 '15 at 07:09
  • I could search the `numpy` `github` issues, and see if anyone is trying to add this to the structured array `__setitem__` method. – hpaulj Oct 13 '15 at 07:37
  • Since all the fields are ints, it possible to `view` these arrays as regular 1 or 2d ones, and use numeric indexing. – hpaulj Oct 13 '15 at 16:53