What is the cleanest way to add a field to a structured numpy array? Can it be done destructively, or is it necessary to create a new array and copy over the existing fields? Are the contents of each field stored contiguously in memory so that such copying can be done efficiently?
Asked
Active
Viewed 9,343 times
2 Answers
20
If you're using numpy 1.3, there's also numpy.lib.recfunctions.append_fields().
For many installations, you'll need to import numpy.lib.recfunctions
to access this. import numpy
will not allow one to see the numpy.lib.recfunctions

Roland
- 499
- 6
- 16

DopplerShift
- 5,472
- 1
- 21
- 20
-
Note that `append_fields` creates an array of type 'numpy.ma.core.MaskedArray'. If you want an array of type 'numpy.ndarray', you can convert the result with `df = np.array(df)`. – nico Jul 17 '23 at 12:03
8
import numpy
def add_field(a, descr):
"""Return a new array that is like "a", but has additional fields.
Arguments:
a -- a structured numpy array
descr -- a numpy type description of the new fields
The contents of "a" are copied over to the appropriate fields in
the new array, whereas the new fields are uninitialized. The
arguments are not modified.
>>> sa = numpy.array([(1, 'Foo'), (2, 'Bar')], \
dtype=[('id', int), ('name', 'S3')])
>>> sa.dtype.descr == numpy.dtype([('id', int), ('name', 'S3')])
True
>>> sb = add_field(sa, [('score', float)])
>>> sb.dtype.descr == numpy.dtype([('id', int), ('name', 'S3'), \
('score', float)])
True
>>> numpy.all(sa['id'] == sb['id'])
True
>>> numpy.all(sa['name'] == sb['name'])
True
"""
if a.dtype.fields is None:
raise ValueError, "`A' must be a structured numpy array"
b = numpy.empty(a.shape, dtype=a.dtype.descr + descr)
for name in a.dtype.names:
b[name] = a[name]
return b

strpeter
- 2,562
- 3
- 27
- 48

Vebjorn Ljosa
- 17,438
- 13
- 70
- 88
-
1Can this be amended to avoid duplicating memory? (see [this question](http://stackoverflow.com/q/39965994/974555)) – gerrit Oct 10 '16 at 20:21