2

I have an nd-array with names fields as below. I'm trying to assign values to multiple fields at once, but it seems to have no effect at all. See the example below:

In [380]: A = numpy.zeros(dtype=[("A", "f8"), ("B", "f8"), ("C", "f8")], shape=(5,))                                                                                                                 

In [381]: A[["A", "B", "C"]][0] = (2, 3, 4)

I would expect that now, these values are assigned to A, but in fact, the array is still all-zero:

In [382]: A[0]
Out[382]: (0.0, 0.0, 0.0)

When I index the other way around, I get an IndexError; (A[0]["A"] works, but A[0][["A", "B", "C"]] is IndexError:

In [383]: A[0][["A", "B", "C"]] = (2, 3, 4)
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-383-9b5cca19867a> in <module>()
----> 1 A[0][["A", "B", "C"]] = (2, 3, 4)

IndexError: invalid index

Why does A[fieldnames][0] = values not assign anything? Why does A[0][fieldnames] fail with an IndexError? How can I write multiple values at once to a structured array (apart from looping explicitly)?

2
  • 1
    Presumably you mean you want to write to multiple but not all fields? Because to do what you're showing, you can just use A[0] = 2, 3, 4 Commented Apr 4, 2014 at 15:07
  • @askewchan Right, in the current simplified example that works, but that works only if (1) I write to all fields (2) my values come in the same order as the fields Commented Apr 4, 2014 at 20:11

2 Answers 2

1

If you really want to set all three fields, as you show in your example, you can simply just select the first entry:

A[0] = 2, 3, 4

In the other case (like A[['A','B']][0] = 2, 3) this might help you understand a little:

FutureWarning: Numpy has detected that you (may be) writing to an array returned
by numpy.diagonal or by selecting multiple fields in a record
array. This code will likely break in a future numpy release --
see numpy.diagonal or arrays.indexing reference docs for details.
The quick fix is to make an explicit copy (e.g., do
arr.diagonal().copy() or arr[['f0','f1']].copy()).

This will probably be made easier in future versions of numpy, because indexing with several fields will soon return a view:

Record Access

If the ndarray object is a record array, i.e. its data type is a record data type, the fields of the array can be accessed by indexing the array with strings, dictionary-like.

Indexing x['field-name'] returns a new view to the array, which is of the same shape as x (except when the field is a sub-array) but of data type x.dtype['field-name'] and contains only the part of the data in the specified field. Also record array scalars can be “indexed” this way.

Indexing into a record array can also be done with a list of field names, e.g. x[['field-name1','field-name2']]. Currently this returns a new array containing a copy of the values in the fields specified in the list. As of NumPy 1.7, returning a copy is being deprecated in favor of returning a view. A copy will continue to be returned for now, but a FutureWarning will be issued when writing to the copy. If you depend on the current behavior, then we suggest copying the returned array explicitly, i.e. use x[[‘field-name1’,’field-name2’]].copy(). This will work with both past and future versions of NumPy.

Sign up to request clarification or add additional context in comments.

Comments

0
  • A[fieldnames][0] = values assigns nothing because you are assigning the value to a copy of the array, returned by A[fieldnames].

  • A[0][["A", "B", "C"]] fails because as the message says ["A", "B", "C"] is an invalid index. You want to use A[0]=2,3,4.

2 Comments

You can avoid the invalid index by slicing: A[:1][["A", "B", "C"]] but you still can't assign to that slice.
right, though that would create a copy of the slice in any case. You can again use A[:1]=2,3,4.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.