<p dir="auto"><em>Original ticket <a href="http://projects.scipy.org/numpy/ticket/1415" rel="nofollow">http://projects.scipy.org/numpy/ticket/1415</a> on 2010-02-27 by trac user mspacek, assigned to unknown.</em></p>
<p dir="auto">See thread at <a href="http://article.gmane.org/gmane.comp.python.numeric.general/36611" rel="nofollow">http://article.gmane.org/gmane.comp.python.numeric.general/36611</a></p>
<p dir="auto">Pickling and then unpickling an entry of &lt;type 'numpy.void'&gt; or &lt;type 'numpy.record'&gt; from a structured array or recarray results in data corruption on the round trip:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="&gt;&gt;&gt; import numpy as np
&gt;&gt;&gt; x = np.zeros((2,), dtype=('i4,f4,a10'))
&gt;&gt;&gt; x[:] = [(1,2.,'Hello'), (2,3.,&quot;World&quot;)]
&gt;&gt;&gt; x
array([(1, 2.0, 'Hello'), (2, 3.0, 'World')],
       dtype=[('f0', '&lt;i4'), ('f1', '&lt;f4'), ('f2', '|S10')])
&gt;&gt;&gt; x[0]
(1, 2.0, 'Hello')
&gt;&gt;&gt; type(x[0])
&lt;type 'numpy.void'&gt;
&gt;&gt;&gt; import pickle
&gt;&gt;&gt; s = pickle.dumps(x[0])
&gt;&gt;&gt; newx0 = pickle.loads(s)
&gt;&gt;&gt; newx0
(30917960, 1.6904535998413144e-38, '\xd0\xef\x1c\x1eZ\x03\x00d')
&gt;&gt;&gt; s
&quot;cnumpy.core.multiarray\nscalar\np0\n(cnumpy\ndtype\np1\n(S'V18'
\np2\nI0\nI1\ntp3\nRp4\n(I4\nS'|'\np5\nN(S'f0'\np6\nS'f1'\np7\nS'f2'
\np8\ntp9\n(dp10\ng6\n(g1\n(S'i4'\np11\nI0\nI1\ntp12\nRp13
\n(I4\nS'&lt;'\np14\nNNNI-1\nI-1\nI0\nNtp15\nbI0\ntp16\nsg7\n(g1
\n(S'f4'\np17\nI0\nI1\ntp18\nRp19\n(I4\nS'&lt;'\np20\nNNNI-1\nI-1
\nI0\nNtp21\nbI4\ntp22\nsg8\n(g1\n(S'S10'\np23\nI0\nI1\ntp24\nRp25
\n(I4\nS'|'\np26\nNNNI10\nI1\nI0\nNtp27\nbI8\ntp28\nsI18\nI1\nI0
\nNtp29\nbS'\\x01\\x00\\x00\\x00\\x00\\x00\\x00@Hello\\x00\\x00
\\x00\\x00\\x00'\np30\ntp31\nRp32\n.&quot;
&gt;&gt;&gt; type(newx0)
&lt;type 'numpy.void'&gt;
&gt;&gt;&gt; newx0.dtype
dtype([('f0', '&lt;i4'), ('f1', '&lt;f4'), ('f2', '|S10')])
&gt;&gt;&gt; x[0].dtype
dtype([('f0', '&lt;i4'), ('f1', '&lt;f4'), ('f2', '|S10')])
&gt;&gt;&gt; np.version.version
'1.4.0'"><pre class="notranslate"><code class="notranslate">&gt;&gt;&gt; import numpy as np
&gt;&gt;&gt; x = np.zeros((2,), dtype=('i4,f4,a10'))
&gt;&gt;&gt; x[:] = [(1,2.,'Hello'), (2,3.,"World")]
&gt;&gt;&gt; x
array([(1, 2.0, 'Hello'), (2, 3.0, 'World')],
       dtype=[('f0', '&lt;i4'), ('f1', '&lt;f4'), ('f2', '|S10')])
&gt;&gt;&gt; x[0]
(1, 2.0, 'Hello')
&gt;&gt;&gt; type(x[0])
&lt;type 'numpy.void'&gt;
&gt;&gt;&gt; import pickle
&gt;&gt;&gt; s = pickle.dumps(x[0])
&gt;&gt;&gt; newx0 = pickle.loads(s)
&gt;&gt;&gt; newx0
(30917960, 1.6904535998413144e-38, '\xd0\xef\x1c\x1eZ\x03\x00d')
&gt;&gt;&gt; s
"cnumpy.core.multiarray\nscalar\np0\n(cnumpy\ndtype\np1\n(S'V18'
\np2\nI0\nI1\ntp3\nRp4\n(I4\nS'|'\np5\nN(S'f0'\np6\nS'f1'\np7\nS'f2'
\np8\ntp9\n(dp10\ng6\n(g1\n(S'i4'\np11\nI0\nI1\ntp12\nRp13
\n(I4\nS'&lt;'\np14\nNNNI-1\nI-1\nI0\nNtp15\nbI0\ntp16\nsg7\n(g1
\n(S'f4'\np17\nI0\nI1\ntp18\nRp19\n(I4\nS'&lt;'\np20\nNNNI-1\nI-1
\nI0\nNtp21\nbI4\ntp22\nsg8\n(g1\n(S'S10'\np23\nI0\nI1\ntp24\nRp25
\n(I4\nS'|'\np26\nNNNI10\nI1\nI0\nNtp27\nbI8\ntp28\nsI18\nI1\nI0
\nNtp29\nbS'\\x01\\x00\\x00\\x00\\x00\\x00\\x00@Hello\\x00\\x00
\\x00\\x00\\x00'\np30\ntp31\nRp32\n."
&gt;&gt;&gt; type(newx0)
&lt;type 'numpy.void'&gt;
&gt;&gt;&gt; newx0.dtype
dtype([('f0', '&lt;i4'), ('f1', '&lt;f4'), ('f2', '|S10')])
&gt;&gt;&gt; x[0].dtype
dtype([('f0', '&lt;i4'), ('f1', '&lt;f4'), ('f2', '|S10')])
&gt;&gt;&gt; np.version.version
'1.4.0'
</code></pre></div>
<p dir="auto">It seems that the pickling works fine, but there's corruption on unpickling.</p>
<p dir="auto">Robert Kern says: "The implementation of numpy.core.multiarray.scalar is doing something wrong."</p>
<p dir="auto">Pauli Virtanen says: "The relevant code path to look at is multiarraymodule:array_scalar -&gt; scalarapi.c:PyArray_Scalar. Needs some cgdb'ing to find out what's going on there."</p>
<p dir="auto">A nice temporary workaround is to convert the original structured array "x" into a list of scalar arrays, each of whose entries then pickle/unpickle correctly, and still allow dict-style named field access:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="&gt;&gt;&gt; x2 = map(np.asarray, x)"><pre class="notranslate"><code class="notranslate">&gt;&gt;&gt; x2 = map(np.asarray, x)
</code></pre></div>
<p dir="auto"><em>Original ticket <a href="http://projects.scipy.org/numpy/ticket/952" rel="nofollow">http://projects.scipy.org/numpy/ticket/952</a> on 2008-11-07 by trac user philbinj, assigned to unknown.</em></p>
<p dir="auto">As per the summary. Unpickling a pickled recarray element returns garbage data.</p>
<p dir="auto">With numpy.<strong>version</strong>=='1.3.0.dev5883':</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="In [1]: import numpy as np

In [2]: dtype = [('r','f4'),('g','f4'),('b','f4')]

In [3]: arr = np.ones((10,), dtype=dtype)

In [4]: arr
Out[4]:
array([(1.0, 1.0, 1.0), (1.0, 1.0, 1.0), (1.0, 1.0, 1.0), (1.0, 1.0, 1.0),
      (1.0, 1.0, 1.0), (1.0, 1.0, 1.0), (1.0, 1.0, 1.0), (1.0, 1.0, 1.0),
      (1.0, 1.0, 1.0), (1.0, 1.0, 1.0)],
     dtype=[('r', '&lt;f4'), ('g', '&lt;f4'), ('b', '&lt;f4')])

In [5]: arr[0]
Out[5]: (1.0, 1.0, 1.0)

In [6]: import cPickle; cPickle.loads(cPickle.dumps(arr[0]))
Out[6]: (0.0, 0.0, 1.8643547392640242e-38)"><pre class="notranslate"><code class="notranslate">In [1]: import numpy as np

In [2]: dtype = [('r','f4'),('g','f4'),('b','f4')]

In [3]: arr = np.ones((10,), dtype=dtype)

In [4]: arr
Out[4]:
array([(1.0, 1.0, 1.0), (1.0, 1.0, 1.0), (1.0, 1.0, 1.0), (1.0, 1.0, 1.0),
      (1.0, 1.0, 1.0), (1.0, 1.0, 1.0), (1.0, 1.0, 1.0), (1.0, 1.0, 1.0),
      (1.0, 1.0, 1.0), (1.0, 1.0, 1.0)],
     dtype=[('r', '&lt;f4'), ('g', '&lt;f4'), ('b', '&lt;f4')])

In [5]: arr[0]
Out[5]: (1.0, 1.0, 1.0)

In [6]: import cPickle; cPickle.loads(cPickle.dumps(arr[0]))
Out[6]: (0.0, 0.0, 1.8643547392640242e-38)
</code></pre></div>