I couldn't find np.lib.recfunctions.merge_arrays. Maybe we have different numpy versions. Rather than dig around for it, I'll do the merger myself, using methods that I've seen in other rec functions.
Your samples:
In [2]: D = np.array([('a', 12), ('b', 14), ('c', 10)],
dtype=np.dtype([('label','a2'), ('ht', 'i2')]))
In [3]: xxx = np.array([[1,2,3],[5,6,7],[78,88,98]])
In [6]: D.dtype
Out[6]: dtype([('label', 'S2'), ('ht', '<i2')])
Define a new dtype for E. This could be built from D.dtype, but I'll just type it in.
In [9]: dt=np.dtype([('label', 'S2'), ('ht', '<i2'),
('xxx', xxx.dtype,xxx.shape[1])])
And a new blank array of the right shape and dtype:
In [11]: E=np.zeros(D.shape, dtype=dt)
In [12]: E
Out[12]:
array([('', 0, [0, 0, 0]), ('', 0, [0, 0, 0]), ('', 0, [0, 0, 0])],
dtype=[('label', 'S2'), ('ht', '<i2'), ('xxx', '<i4', (3,))])
Now copy fields from D and xxx. This kind of is common in the rec functions. There isn't anything more streamlined for compound dtypes.
In [13]: for name in D.dtype.names:
....: E[name] = D[name]
In [14]: E['xxx']=xxx
In [15]: E
Out[15]:
array([('a', 12, [1, 2, 3]), ('b', 14, [5, 6, 7]), ('c', 10, [78, 88, 98])],
dtype=[('label', 'S2'), ('ht', '<i2'), ('xxx', '<i4', (3,))])
That's your target, right?
For some reason I have to import recfunctions separately. That's not usual for numpy.
from numpy.lib import recfunctions
When mentioning merge_arrays and append_field, you really should describe what didn't work, whether it was an error, or you didn't like the result.
merge_array does work:
In [35]: e=recfunctions.merge_arrays((D,xxx))
Out[35]:
array([(('a', 12), 1), (('b', 14), 2), (('c', 10), 3), (('-1', -1), 5),
(('-1', -1), 6), (('-1', -1), 7), (('-1', -1), 78),
(('-1', -1), 88), (('-1', -1), 98)],
dtype=[('f0', [('label', 'S2'), ('ht', '<i2')]), ('f1', '<i4')])
It's just that the 2 input arrays are separate fields:
In [38]: e['f0']
Out[38]:
array([('a', 12), ('b', 14), ('c', 10), ('-1', -1), ('-1', -1), ('-1', -1),('-1', -1), ('-1', -1), ('-1', -1)],
dtype=[('label', 'S2'), ('ht', '<i2')])
In [39]: e['f1']
Out[39]: array([ 1, 2, 3, 5, 6, 7, 78, 88, 98])
append_fields works for a simple addition, but not for xxx with 3 columns
In [57]: recfunctions.append_fields(D,'xxx',[1,2,3],usemask=False)
Out[57]:
array([('a', 12, 1), ('b', 14, 2), ('c', 10, 3)],
dtype=[('label', 'S2'), ('ht', '<i2'), ('xxx', '<i4')])
Or I could turn xxx into a structured array, and append that:
In [60]: x1=np.zeros((3,),dtype=[('xxx',int,(3,))])
In [61]: x1['xxx']=xxx
In [62]: x1
Out[62]:
array([([1, 2, 3],), ([5, 6, 7],), ([78, 88, 98],)],
dtype=[('xxx', '<i4', (3,))])
In [63]: recfunctions.append_fields(D,'xxx',x1,usemask=False)
Out[63]:
array([('a', 12, ([1, 2, 3],)), ('b', 14, ([5, 6, 7],)),
('c', 10, ([78, 88, 98],))],
dtype=[('label', 'S2'), ('ht', '<i2'), ('xxx', [('xxx', '<i4', (3,))])])
Closer, but not quite right. I could keep playing with these functions, but is it worth it?
These are equivalent, though recursive_fill handles more complex dtypes:
recfunctions.recursive_fill_fields(D,E)
for name in D.dtype.names: E[name] = D[name]
Here's a way of building E.dtype with recfunctions, but there's got to be something simpler:
dt2=list(recfunctions.flatten_descr(np.dtype(recfunctions.zip_descr([D,x1]))))