How do I fill multiple named fields using structur

2019-07-02 12:24发布

问题:

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?

回答1:

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).