test_mrecords.py 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. # pylint: disable-msg=W0611, W0612, W0511,R0201
  2. """Tests suite for mrecords.
  3. :author: Pierre Gerard-Marchant
  4. :contact: pierregm_at_uga_dot_edu
  5. """
  6. import numpy as np
  7. import numpy.ma as ma
  8. from numpy import recarray
  9. from numpy.ma import masked, nomask
  10. from numpy.testing import temppath
  11. from numpy.core.records import (
  12. fromrecords as recfromrecords, fromarrays as recfromarrays
  13. )
  14. from numpy.ma.mrecords import (
  15. MaskedRecords, mrecarray, fromarrays, fromtextfile, fromrecords,
  16. addfield
  17. )
  18. from numpy.ma.testutils import (
  19. assert_, assert_equal,
  20. assert_equal_records,
  21. )
  22. from numpy.compat import pickle
  23. class TestMRecords:
  24. ilist = [1, 2, 3, 4, 5]
  25. flist = [1.1, 2.2, 3.3, 4.4, 5.5]
  26. slist = [b'one', b'two', b'three', b'four', b'five']
  27. ddtype = [('a', int), ('b', float), ('c', '|S8')]
  28. mask = [0, 1, 0, 0, 1]
  29. base = ma.array(list(zip(ilist, flist, slist)), mask=mask, dtype=ddtype)
  30. def test_byview(self):
  31. # Test creation by view
  32. base = self.base
  33. mbase = base.view(mrecarray)
  34. assert_equal(mbase.recordmask, base.recordmask)
  35. assert_equal_records(mbase._mask, base._mask)
  36. assert_(isinstance(mbase._data, recarray))
  37. assert_equal_records(mbase._data, base._data.view(recarray))
  38. for field in ('a', 'b', 'c'):
  39. assert_equal(base[field], mbase[field])
  40. assert_equal_records(mbase.view(mrecarray), mbase)
  41. def test_get(self):
  42. # Tests fields retrieval
  43. base = self.base.copy()
  44. mbase = base.view(mrecarray)
  45. # As fields..........
  46. for field in ('a', 'b', 'c'):
  47. assert_equal(getattr(mbase, field), mbase[field])
  48. assert_equal(base[field], mbase[field])
  49. # as elements .......
  50. mbase_first = mbase[0]
  51. assert_(isinstance(mbase_first, mrecarray))
  52. assert_equal(mbase_first.dtype, mbase.dtype)
  53. assert_equal(mbase_first.tolist(), (1, 1.1, b'one'))
  54. # Used to be mask, now it's recordmask
  55. assert_equal(mbase_first.recordmask, nomask)
  56. assert_equal(mbase_first._mask.item(), (False, False, False))
  57. assert_equal(mbase_first['a'], mbase['a'][0])
  58. mbase_last = mbase[-1]
  59. assert_(isinstance(mbase_last, mrecarray))
  60. assert_equal(mbase_last.dtype, mbase.dtype)
  61. assert_equal(mbase_last.tolist(), (None, None, None))
  62. # Used to be mask, now it's recordmask
  63. assert_equal(mbase_last.recordmask, True)
  64. assert_equal(mbase_last._mask.item(), (True, True, True))
  65. assert_equal(mbase_last['a'], mbase['a'][-1])
  66. assert_((mbase_last['a'] is masked))
  67. # as slice ..........
  68. mbase_sl = mbase[:2]
  69. assert_(isinstance(mbase_sl, mrecarray))
  70. assert_equal(mbase_sl.dtype, mbase.dtype)
  71. # Used to be mask, now it's recordmask
  72. assert_equal(mbase_sl.recordmask, [0, 1])
  73. assert_equal_records(mbase_sl.mask,
  74. np.array([(False, False, False),
  75. (True, True, True)],
  76. dtype=mbase._mask.dtype))
  77. assert_equal_records(mbase_sl, base[:2].view(mrecarray))
  78. for field in ('a', 'b', 'c'):
  79. assert_equal(getattr(mbase_sl, field), base[:2][field])
  80. def test_set_fields(self):
  81. # Tests setting fields.
  82. base = self.base.copy()
  83. mbase = base.view(mrecarray)
  84. mbase = mbase.copy()
  85. mbase.fill_value = (999999, 1e20, 'N/A')
  86. # Change the data, the mask should be conserved
  87. mbase.a._data[:] = 5
  88. assert_equal(mbase['a']._data, [5, 5, 5, 5, 5])
  89. assert_equal(mbase['a']._mask, [0, 1, 0, 0, 1])
  90. # Change the elements, and the mask will follow
  91. mbase.a = 1
  92. assert_equal(mbase['a']._data, [1]*5)
  93. assert_equal(ma.getmaskarray(mbase['a']), [0]*5)
  94. # Use to be _mask, now it's recordmask
  95. assert_equal(mbase.recordmask, [False]*5)
  96. assert_equal(mbase._mask.tolist(),
  97. np.array([(0, 0, 0),
  98. (0, 1, 1),
  99. (0, 0, 0),
  100. (0, 0, 0),
  101. (0, 1, 1)],
  102. dtype=bool))
  103. # Set a field to mask ........................
  104. mbase.c = masked
  105. # Use to be mask, and now it's still mask !
  106. assert_equal(mbase.c.mask, [1]*5)
  107. assert_equal(mbase.c.recordmask, [1]*5)
  108. assert_equal(ma.getmaskarray(mbase['c']), [1]*5)
  109. assert_equal(ma.getdata(mbase['c']), [b'N/A']*5)
  110. assert_equal(mbase._mask.tolist(),
  111. np.array([(0, 0, 1),
  112. (0, 1, 1),
  113. (0, 0, 1),
  114. (0, 0, 1),
  115. (0, 1, 1)],
  116. dtype=bool))
  117. # Set fields by slices .......................
  118. mbase = base.view(mrecarray).copy()
  119. mbase.a[3:] = 5
  120. assert_equal(mbase.a, [1, 2, 3, 5, 5])
  121. assert_equal(mbase.a._mask, [0, 1, 0, 0, 0])
  122. mbase.b[3:] = masked
  123. assert_equal(mbase.b, base['b'])
  124. assert_equal(mbase.b._mask, [0, 1, 0, 1, 1])
  125. # Set fields globally..........................
  126. ndtype = [('alpha', '|S1'), ('num', int)]
  127. data = ma.array([('a', 1), ('b', 2), ('c', 3)], dtype=ndtype)
  128. rdata = data.view(MaskedRecords)
  129. val = ma.array([10, 20, 30], mask=[1, 0, 0])
  130. rdata['num'] = val
  131. assert_equal(rdata.num, val)
  132. assert_equal(rdata.num.mask, [1, 0, 0])
  133. def test_set_fields_mask(self):
  134. # Tests setting the mask of a field.
  135. base = self.base.copy()
  136. # This one has already a mask....
  137. mbase = base.view(mrecarray)
  138. mbase['a'][-2] = masked
  139. assert_equal(mbase.a, [1, 2, 3, 4, 5])
  140. assert_equal(mbase.a._mask, [0, 1, 0, 1, 1])
  141. # This one has not yet
  142. mbase = fromarrays([np.arange(5), np.random.rand(5)],
  143. dtype=[('a', int), ('b', float)])
  144. mbase['a'][-2] = masked
  145. assert_equal(mbase.a, [0, 1, 2, 3, 4])
  146. assert_equal(mbase.a._mask, [0, 0, 0, 1, 0])
  147. def test_set_mask(self):
  148. base = self.base.copy()
  149. mbase = base.view(mrecarray)
  150. # Set the mask to True .......................
  151. mbase.mask = masked
  152. assert_equal(ma.getmaskarray(mbase['b']), [1]*5)
  153. assert_equal(mbase['a']._mask, mbase['b']._mask)
  154. assert_equal(mbase['a']._mask, mbase['c']._mask)
  155. assert_equal(mbase._mask.tolist(),
  156. np.array([(1, 1, 1)]*5, dtype=bool))
  157. # Delete the mask ............................
  158. mbase.mask = nomask
  159. assert_equal(ma.getmaskarray(mbase['c']), [0]*5)
  160. assert_equal(mbase._mask.tolist(),
  161. np.array([(0, 0, 0)]*5, dtype=bool))
  162. def test_set_mask_fromarray(self):
  163. base = self.base.copy()
  164. mbase = base.view(mrecarray)
  165. # Sets the mask w/ an array
  166. mbase.mask = [1, 0, 0, 0, 1]
  167. assert_equal(mbase.a.mask, [1, 0, 0, 0, 1])
  168. assert_equal(mbase.b.mask, [1, 0, 0, 0, 1])
  169. assert_equal(mbase.c.mask, [1, 0, 0, 0, 1])
  170. # Yay, once more !
  171. mbase.mask = [0, 0, 0, 0, 1]
  172. assert_equal(mbase.a.mask, [0, 0, 0, 0, 1])
  173. assert_equal(mbase.b.mask, [0, 0, 0, 0, 1])
  174. assert_equal(mbase.c.mask, [0, 0, 0, 0, 1])
  175. def test_set_mask_fromfields(self):
  176. mbase = self.base.copy().view(mrecarray)
  177. nmask = np.array(
  178. [(0, 1, 0), (0, 1, 0), (1, 0, 1), (1, 0, 1), (0, 0, 0)],
  179. dtype=[('a', bool), ('b', bool), ('c', bool)])
  180. mbase.mask = nmask
  181. assert_equal(mbase.a.mask, [0, 0, 1, 1, 0])
  182. assert_equal(mbase.b.mask, [1, 1, 0, 0, 0])
  183. assert_equal(mbase.c.mask, [0, 0, 1, 1, 0])
  184. # Reinitialize and redo
  185. mbase.mask = False
  186. mbase.fieldmask = nmask
  187. assert_equal(mbase.a.mask, [0, 0, 1, 1, 0])
  188. assert_equal(mbase.b.mask, [1, 1, 0, 0, 0])
  189. assert_equal(mbase.c.mask, [0, 0, 1, 1, 0])
  190. def test_set_elements(self):
  191. base = self.base.copy()
  192. # Set an element to mask .....................
  193. mbase = base.view(mrecarray).copy()
  194. mbase[-2] = masked
  195. assert_equal(
  196. mbase._mask.tolist(),
  197. np.array([(0, 0, 0), (1, 1, 1), (0, 0, 0), (1, 1, 1), (1, 1, 1)],
  198. dtype=bool))
  199. # Used to be mask, now it's recordmask!
  200. assert_equal(mbase.recordmask, [0, 1, 0, 1, 1])
  201. # Set slices .................................
  202. mbase = base.view(mrecarray).copy()
  203. mbase[:2] = (5, 5, 5)
  204. assert_equal(mbase.a._data, [5, 5, 3, 4, 5])
  205. assert_equal(mbase.a._mask, [0, 0, 0, 0, 1])
  206. assert_equal(mbase.b._data, [5., 5., 3.3, 4.4, 5.5])
  207. assert_equal(mbase.b._mask, [0, 0, 0, 0, 1])
  208. assert_equal(mbase.c._data,
  209. [b'5', b'5', b'three', b'four', b'five'])
  210. assert_equal(mbase.b._mask, [0, 0, 0, 0, 1])
  211. mbase = base.view(mrecarray).copy()
  212. mbase[:2] = masked
  213. assert_equal(mbase.a._data, [1, 2, 3, 4, 5])
  214. assert_equal(mbase.a._mask, [1, 1, 0, 0, 1])
  215. assert_equal(mbase.b._data, [1.1, 2.2, 3.3, 4.4, 5.5])
  216. assert_equal(mbase.b._mask, [1, 1, 0, 0, 1])
  217. assert_equal(mbase.c._data,
  218. [b'one', b'two', b'three', b'four', b'five'])
  219. assert_equal(mbase.b._mask, [1, 1, 0, 0, 1])
  220. def test_setslices_hardmask(self):
  221. # Tests setting slices w/ hardmask.
  222. base = self.base.copy()
  223. mbase = base.view(mrecarray)
  224. mbase.harden_mask()
  225. try:
  226. mbase[-2:] = (5, 5, 5)
  227. assert_equal(mbase.a._data, [1, 2, 3, 5, 5])
  228. assert_equal(mbase.b._data, [1.1, 2.2, 3.3, 5, 5.5])
  229. assert_equal(mbase.c._data,
  230. [b'one', b'two', b'three', b'5', b'five'])
  231. assert_equal(mbase.a._mask, [0, 1, 0, 0, 1])
  232. assert_equal(mbase.b._mask, mbase.a._mask)
  233. assert_equal(mbase.b._mask, mbase.c._mask)
  234. except NotImplementedError:
  235. # OK, not implemented yet...
  236. pass
  237. except AssertionError:
  238. raise
  239. else:
  240. raise Exception("Flexible hard masks should be supported !")
  241. # Not using a tuple should crash
  242. try:
  243. mbase[-2:] = 3
  244. except (NotImplementedError, TypeError):
  245. pass
  246. else:
  247. raise TypeError("Should have expected a readable buffer object!")
  248. def test_hardmask(self):
  249. # Test hardmask
  250. base = self.base.copy()
  251. mbase = base.view(mrecarray)
  252. mbase.harden_mask()
  253. assert_(mbase._hardmask)
  254. mbase.mask = nomask
  255. assert_equal_records(mbase._mask, base._mask)
  256. mbase.soften_mask()
  257. assert_(not mbase._hardmask)
  258. mbase.mask = nomask
  259. # So, the mask of a field is no longer set to nomask...
  260. assert_equal_records(mbase._mask,
  261. ma.make_mask_none(base.shape, base.dtype))
  262. assert_(ma.make_mask(mbase['b']._mask) is nomask)
  263. assert_equal(mbase['a']._mask, mbase['b']._mask)
  264. def test_pickling(self):
  265. # Test pickling
  266. base = self.base.copy()
  267. mrec = base.view(mrecarray)
  268. for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
  269. _ = pickle.dumps(mrec, protocol=proto)
  270. mrec_ = pickle.loads(_)
  271. assert_equal(mrec_.dtype, mrec.dtype)
  272. assert_equal_records(mrec_._data, mrec._data)
  273. assert_equal(mrec_._mask, mrec._mask)
  274. assert_equal_records(mrec_._mask, mrec._mask)
  275. def test_filled(self):
  276. # Test filling the array
  277. _a = ma.array([1, 2, 3], mask=[0, 0, 1], dtype=int)
  278. _b = ma.array([1.1, 2.2, 3.3], mask=[0, 0, 1], dtype=float)
  279. _c = ma.array(['one', 'two', 'three'], mask=[0, 0, 1], dtype='|S8')
  280. ddtype = [('a', int), ('b', float), ('c', '|S8')]
  281. mrec = fromarrays([_a, _b, _c], dtype=ddtype,
  282. fill_value=(99999, 99999., 'N/A'))
  283. mrecfilled = mrec.filled()
  284. assert_equal(mrecfilled['a'], np.array((1, 2, 99999), dtype=int))
  285. assert_equal(mrecfilled['b'], np.array((1.1, 2.2, 99999.),
  286. dtype=float))
  287. assert_equal(mrecfilled['c'], np.array(('one', 'two', 'N/A'),
  288. dtype='|S8'))
  289. def test_tolist(self):
  290. # Test tolist.
  291. _a = ma.array([1, 2, 3], mask=[0, 0, 1], dtype=int)
  292. _b = ma.array([1.1, 2.2, 3.3], mask=[0, 0, 1], dtype=float)
  293. _c = ma.array(['one', 'two', 'three'], mask=[1, 0, 0], dtype='|S8')
  294. ddtype = [('a', int), ('b', float), ('c', '|S8')]
  295. mrec = fromarrays([_a, _b, _c], dtype=ddtype,
  296. fill_value=(99999, 99999., 'N/A'))
  297. assert_equal(mrec.tolist(),
  298. [(1, 1.1, None), (2, 2.2, b'two'),
  299. (None, None, b'three')])
  300. def test_withnames(self):
  301. # Test the creation w/ format and names
  302. x = mrecarray(1, formats=float, names='base')
  303. x[0]['base'] = 10
  304. assert_equal(x['base'][0], 10)
  305. def test_exotic_formats(self):
  306. # Test that 'exotic' formats are processed properly
  307. easy = mrecarray(1, dtype=[('i', int), ('s', '|S8'), ('f', float)])
  308. easy[0] = masked
  309. assert_equal(easy.filled(1).item(), (1, b'1', 1.))
  310. solo = mrecarray(1, dtype=[('f0', '<f8', (2, 2))])
  311. solo[0] = masked
  312. assert_equal(solo.filled(1).item(),
  313. np.array((1,), dtype=solo.dtype).item())
  314. mult = mrecarray(2, dtype="i4, (2,3)float, float")
  315. mult[0] = masked
  316. mult[1] = (1, 1, 1)
  317. mult.filled(0)
  318. assert_equal_records(mult.filled(0),
  319. np.array([(0, 0, 0), (1, 1, 1)],
  320. dtype=mult.dtype))
  321. class TestView:
  322. def setup_method(self):
  323. (a, b) = (np.arange(10), np.random.rand(10))
  324. ndtype = [('a', float), ('b', float)]
  325. arr = np.array(list(zip(a, b)), dtype=ndtype)
  326. mrec = fromarrays([a, b], dtype=ndtype, fill_value=(-9., -99.))
  327. mrec.mask[3] = (False, True)
  328. self.data = (mrec, a, b, arr)
  329. def test_view_by_itself(self):
  330. (mrec, a, b, arr) = self.data
  331. test = mrec.view()
  332. assert_(isinstance(test, MaskedRecords))
  333. assert_equal_records(test, mrec)
  334. assert_equal_records(test._mask, mrec._mask)
  335. def test_view_simple_dtype(self):
  336. (mrec, a, b, arr) = self.data
  337. ntype = (float, 2)
  338. test = mrec.view(ntype)
  339. assert_(isinstance(test, ma.MaskedArray))
  340. assert_equal(test, np.array(list(zip(a, b)), dtype=float))
  341. assert_(test[3, 1] is ma.masked)
  342. def test_view_flexible_type(self):
  343. (mrec, a, b, arr) = self.data
  344. alttype = [('A', float), ('B', float)]
  345. test = mrec.view(alttype)
  346. assert_(isinstance(test, MaskedRecords))
  347. assert_equal_records(test, arr.view(alttype))
  348. assert_(test['B'][3] is masked)
  349. assert_equal(test.dtype, np.dtype(alttype))
  350. assert_(test._fill_value is None)
  351. ##############################################################################
  352. class TestMRecordsImport:
  353. _a = ma.array([1, 2, 3], mask=[0, 0, 1], dtype=int)
  354. _b = ma.array([1.1, 2.2, 3.3], mask=[0, 0, 1], dtype=float)
  355. _c = ma.array([b'one', b'two', b'three'],
  356. mask=[0, 0, 1], dtype='|S8')
  357. ddtype = [('a', int), ('b', float), ('c', '|S8')]
  358. mrec = fromarrays([_a, _b, _c], dtype=ddtype,
  359. fill_value=(b'99999', b'99999.',
  360. b'N/A'))
  361. nrec = recfromarrays((_a._data, _b._data, _c._data), dtype=ddtype)
  362. data = (mrec, nrec, ddtype)
  363. def test_fromarrays(self):
  364. _a = ma.array([1, 2, 3], mask=[0, 0, 1], dtype=int)
  365. _b = ma.array([1.1, 2.2, 3.3], mask=[0, 0, 1], dtype=float)
  366. _c = ma.array(['one', 'two', 'three'], mask=[0, 0, 1], dtype='|S8')
  367. (mrec, nrec, _) = self.data
  368. for (f, l) in zip(('a', 'b', 'c'), (_a, _b, _c)):
  369. assert_equal(getattr(mrec, f)._mask, l._mask)
  370. # One record only
  371. _x = ma.array([1, 1.1, 'one'], mask=[1, 0, 0], dtype=object)
  372. assert_equal_records(fromarrays(_x, dtype=mrec.dtype), mrec[0])
  373. def test_fromrecords(self):
  374. # Test construction from records.
  375. (mrec, nrec, ddtype) = self.data
  376. #......
  377. palist = [(1, 'abc', 3.7000002861022949, 0),
  378. (2, 'xy', 6.6999998092651367, 1),
  379. (0, ' ', 0.40000000596046448, 0)]
  380. pa = recfromrecords(palist, names='c1, c2, c3, c4')
  381. mpa = fromrecords(palist, names='c1, c2, c3, c4')
  382. assert_equal_records(pa, mpa)
  383. #.....
  384. _mrec = fromrecords(nrec)
  385. assert_equal(_mrec.dtype, mrec.dtype)
  386. for field in _mrec.dtype.names:
  387. assert_equal(getattr(_mrec, field), getattr(mrec._data, field))
  388. _mrec = fromrecords(nrec.tolist(), names='c1,c2,c3')
  389. assert_equal(_mrec.dtype, [('c1', int), ('c2', float), ('c3', '|S5')])
  390. for (f, n) in zip(('c1', 'c2', 'c3'), ('a', 'b', 'c')):
  391. assert_equal(getattr(_mrec, f), getattr(mrec._data, n))
  392. _mrec = fromrecords(mrec)
  393. assert_equal(_mrec.dtype, mrec.dtype)
  394. assert_equal_records(_mrec._data, mrec.filled())
  395. assert_equal_records(_mrec._mask, mrec._mask)
  396. def test_fromrecords_wmask(self):
  397. # Tests construction from records w/ mask.
  398. (mrec, nrec, ddtype) = self.data
  399. _mrec = fromrecords(nrec.tolist(), dtype=ddtype, mask=[0, 1, 0,])
  400. assert_equal_records(_mrec._data, mrec._data)
  401. assert_equal(_mrec._mask.tolist(), [(0, 0, 0), (1, 1, 1), (0, 0, 0)])
  402. _mrec = fromrecords(nrec.tolist(), dtype=ddtype, mask=True)
  403. assert_equal_records(_mrec._data, mrec._data)
  404. assert_equal(_mrec._mask.tolist(), [(1, 1, 1), (1, 1, 1), (1, 1, 1)])
  405. _mrec = fromrecords(nrec.tolist(), dtype=ddtype, mask=mrec._mask)
  406. assert_equal_records(_mrec._data, mrec._data)
  407. assert_equal(_mrec._mask.tolist(), mrec._mask.tolist())
  408. _mrec = fromrecords(nrec.tolist(), dtype=ddtype,
  409. mask=mrec._mask.tolist())
  410. assert_equal_records(_mrec._data, mrec._data)
  411. assert_equal(_mrec._mask.tolist(), mrec._mask.tolist())
  412. def test_fromtextfile(self):
  413. # Tests reading from a text file.
  414. fcontent = (
  415. """#
  416. 'One (S)','Two (I)','Three (F)','Four (M)','Five (-)','Six (C)'
  417. 'strings',1,1.0,'mixed column',,1
  418. 'with embedded "double quotes"',2,2.0,1.0,,1
  419. 'strings',3,3.0E5,3,,1
  420. 'strings',4,-1e-10,,,1
  421. """)
  422. with temppath() as path:
  423. with open(path, 'w') as f:
  424. f.write(fcontent)
  425. mrectxt = fromtextfile(path, delimiter=',', varnames='ABCDEFG')
  426. assert_(isinstance(mrectxt, MaskedRecords))
  427. assert_equal(mrectxt.F, [1, 1, 1, 1])
  428. assert_equal(mrectxt.E._mask, [1, 1, 1, 1])
  429. assert_equal(mrectxt.C, [1, 2, 3.e+5, -1e-10])
  430. def test_addfield(self):
  431. # Tests addfield
  432. (mrec, nrec, ddtype) = self.data
  433. (d, m) = ([100, 200, 300], [1, 0, 0])
  434. mrec = addfield(mrec, ma.array(d, mask=m))
  435. assert_equal(mrec.f3, d)
  436. assert_equal(mrec.f3._mask, m)
  437. def test_record_array_with_object_field():
  438. # Trac #1839
  439. y = ma.masked_array(
  440. [(1, '2'), (3, '4')],
  441. mask=[(0, 0), (0, 1)],
  442. dtype=[('a', int), ('b', object)])
  443. # getting an item used to fail
  444. y[1]