Chris@87: from __future__ import division, absolute_import, print_function Chris@87: Chris@87: import numpy as np Chris@87: import numpy.ma as ma Chris@87: from numpy.ma.mrecords import MaskedRecords Chris@87: from numpy.ma.testutils import ( Chris@87: run_module_suite, TestCase, assert_, assert_equal Chris@87: ) Chris@87: from numpy.lib.recfunctions import ( Chris@87: drop_fields, rename_fields, get_fieldstructure, recursive_fill_fields, Chris@87: find_duplicates, merge_arrays, append_fields, stack_arrays, join_by Chris@87: ) Chris@87: get_names = np.lib.recfunctions.get_names Chris@87: get_names_flat = np.lib.recfunctions.get_names_flat Chris@87: zip_descr = np.lib.recfunctions.zip_descr Chris@87: Chris@87: Chris@87: class TestRecFunctions(TestCase): Chris@87: # Misc tests Chris@87: Chris@87: def setUp(self): Chris@87: x = np.array([1, 2, ]) Chris@87: y = np.array([10, 20, 30]) Chris@87: z = np.array([('A', 1.), ('B', 2.)], Chris@87: dtype=[('A', '|S3'), ('B', float)]) Chris@87: w = np.array([(1, (2, 3.0)), (4, (5, 6.0))], Chris@87: dtype=[('a', int), ('b', [('ba', float), ('bb', int)])]) Chris@87: self.data = (w, x, y, z) Chris@87: Chris@87: def test_zip_descr(self): Chris@87: # Test zip_descr Chris@87: (w, x, y, z) = self.data Chris@87: Chris@87: # Std array Chris@87: test = zip_descr((x, x), flatten=True) Chris@87: assert_equal(test, Chris@87: np.dtype([('', int), ('', int)])) Chris@87: test = zip_descr((x, x), flatten=False) Chris@87: assert_equal(test, Chris@87: np.dtype([('', int), ('', int)])) Chris@87: Chris@87: # Std & flexible-dtype Chris@87: test = zip_descr((x, z), flatten=True) Chris@87: assert_equal(test, Chris@87: np.dtype([('', int), ('A', '|S3'), ('B', float)])) Chris@87: test = zip_descr((x, z), flatten=False) Chris@87: assert_equal(test, Chris@87: np.dtype([('', int), Chris@87: ('', [('A', '|S3'), ('B', float)])])) Chris@87: Chris@87: # Standard & nested dtype Chris@87: test = zip_descr((x, w), flatten=True) Chris@87: assert_equal(test, Chris@87: np.dtype([('', int), Chris@87: ('a', int), Chris@87: ('ba', float), ('bb', int)])) Chris@87: test = zip_descr((x, w), flatten=False) Chris@87: assert_equal(test, Chris@87: np.dtype([('', int), Chris@87: ('', [('a', int), Chris@87: ('b', [('ba', float), ('bb', int)])])])) Chris@87: Chris@87: def test_drop_fields(self): Chris@87: # Test drop_fields Chris@87: a = np.array([(1, (2, 3.0)), (4, (5, 6.0))], Chris@87: dtype=[('a', int), ('b', [('ba', float), ('bb', int)])]) Chris@87: Chris@87: # A basic field Chris@87: test = drop_fields(a, 'a') Chris@87: control = np.array([((2, 3.0),), ((5, 6.0),)], Chris@87: dtype=[('b', [('ba', float), ('bb', int)])]) Chris@87: assert_equal(test, control) Chris@87: Chris@87: # Another basic field (but nesting two fields) Chris@87: test = drop_fields(a, 'b') Chris@87: control = np.array([(1,), (4,)], dtype=[('a', int)]) Chris@87: assert_equal(test, control) Chris@87: Chris@87: # A nested sub-field Chris@87: test = drop_fields(a, ['ba', ]) Chris@87: control = np.array([(1, (3.0,)), (4, (6.0,))], Chris@87: dtype=[('a', int), ('b', [('bb', int)])]) Chris@87: assert_equal(test, control) Chris@87: Chris@87: # All the nested sub-field from a field: zap that field Chris@87: test = drop_fields(a, ['ba', 'bb']) Chris@87: control = np.array([(1,), (4,)], dtype=[('a', int)]) Chris@87: assert_equal(test, control) Chris@87: Chris@87: test = drop_fields(a, ['a', 'b']) Chris@87: assert_(test is None) Chris@87: Chris@87: def test_rename_fields(self): Chris@87: # Test rename fields Chris@87: a = np.array([(1, (2, [3.0, 30.])), (4, (5, [6.0, 60.]))], Chris@87: dtype=[('a', int), Chris@87: ('b', [('ba', float), ('bb', (float, 2))])]) Chris@87: test = rename_fields(a, {'a': 'A', 'bb': 'BB'}) Chris@87: newdtype = [('A', int), ('b', [('ba', float), ('BB', (float, 2))])] Chris@87: control = a.view(newdtype) Chris@87: assert_equal(test.dtype, newdtype) Chris@87: assert_equal(test, control) Chris@87: Chris@87: def test_get_names(self): Chris@87: # Test get_names Chris@87: ndtype = np.dtype([('A', '|S3'), ('B', float)]) Chris@87: test = get_names(ndtype) Chris@87: assert_equal(test, ('A', 'B')) Chris@87: Chris@87: ndtype = np.dtype([('a', int), ('b', [('ba', float), ('bb', int)])]) Chris@87: test = get_names(ndtype) Chris@87: assert_equal(test, ('a', ('b', ('ba', 'bb')))) Chris@87: Chris@87: def test_get_names_flat(self): Chris@87: # Test get_names_flat Chris@87: ndtype = np.dtype([('A', '|S3'), ('B', float)]) Chris@87: test = get_names_flat(ndtype) Chris@87: assert_equal(test, ('A', 'B')) Chris@87: Chris@87: ndtype = np.dtype([('a', int), ('b', [('ba', float), ('bb', int)])]) Chris@87: test = get_names_flat(ndtype) Chris@87: assert_equal(test, ('a', 'b', 'ba', 'bb')) Chris@87: Chris@87: def test_get_fieldstructure(self): Chris@87: # Test get_fieldstructure Chris@87: Chris@87: # No nested fields Chris@87: ndtype = np.dtype([('A', '|S3'), ('B', float)]) Chris@87: test = get_fieldstructure(ndtype) Chris@87: assert_equal(test, {'A': [], 'B': []}) Chris@87: Chris@87: # One 1-nested field Chris@87: ndtype = np.dtype([('A', int), ('B', [('BA', float), ('BB', '|S1')])]) Chris@87: test = get_fieldstructure(ndtype) Chris@87: assert_equal(test, {'A': [], 'B': [], 'BA': ['B', ], 'BB': ['B']}) Chris@87: Chris@87: # One 2-nested fields Chris@87: ndtype = np.dtype([('A', int), Chris@87: ('B', [('BA', int), Chris@87: ('BB', [('BBA', int), ('BBB', int)])])]) Chris@87: test = get_fieldstructure(ndtype) Chris@87: control = {'A': [], 'B': [], 'BA': ['B'], 'BB': ['B'], Chris@87: 'BBA': ['B', 'BB'], 'BBB': ['B', 'BB']} Chris@87: assert_equal(test, control) Chris@87: Chris@87: def test_find_duplicates(self): Chris@87: # Test find_duplicates Chris@87: a = ma.array([(2, (2., 'B')), (1, (2., 'B')), (2, (2., 'B')), Chris@87: (1, (1., 'B')), (2, (2., 'B')), (2, (2., 'C'))], Chris@87: mask=[(0, (0, 0)), (0, (0, 0)), (0, (0, 0)), Chris@87: (0, (0, 0)), (1, (0, 0)), (0, (1, 0))], Chris@87: dtype=[('A', int), ('B', [('BA', float), ('BB', '|S1')])]) Chris@87: Chris@87: test = find_duplicates(a, ignoremask=False, return_index=True) Chris@87: control = [0, 2] Chris@87: assert_equal(sorted(test[-1]), control) Chris@87: assert_equal(test[0], a[test[-1]]) Chris@87: Chris@87: test = find_duplicates(a, key='A', return_index=True) Chris@87: control = [0, 1, 2, 3, 5] Chris@87: assert_equal(sorted(test[-1]), control) Chris@87: assert_equal(test[0], a[test[-1]]) Chris@87: Chris@87: test = find_duplicates(a, key='B', return_index=True) Chris@87: control = [0, 1, 2, 4] Chris@87: assert_equal(sorted(test[-1]), control) Chris@87: assert_equal(test[0], a[test[-1]]) Chris@87: Chris@87: test = find_duplicates(a, key='BA', return_index=True) Chris@87: control = [0, 1, 2, 4] Chris@87: assert_equal(sorted(test[-1]), control) Chris@87: assert_equal(test[0], a[test[-1]]) Chris@87: Chris@87: test = find_duplicates(a, key='BB', return_index=True) Chris@87: control = [0, 1, 2, 3, 4] Chris@87: assert_equal(sorted(test[-1]), control) Chris@87: assert_equal(test[0], a[test[-1]]) Chris@87: Chris@87: def test_find_duplicates_ignoremask(self): Chris@87: # Test the ignoremask option of find_duplicates Chris@87: ndtype = [('a', int)] Chris@87: a = ma.array([1, 1, 1, 2, 2, 3, 3], Chris@87: mask=[0, 0, 1, 0, 0, 0, 1]).view(ndtype) Chris@87: test = find_duplicates(a, ignoremask=True, return_index=True) Chris@87: control = [0, 1, 3, 4] Chris@87: assert_equal(sorted(test[-1]), control) Chris@87: assert_equal(test[0], a[test[-1]]) Chris@87: Chris@87: test = find_duplicates(a, ignoremask=False, return_index=True) Chris@87: control = [0, 1, 2, 3, 4, 6] Chris@87: assert_equal(sorted(test[-1]), control) Chris@87: assert_equal(test[0], a[test[-1]]) Chris@87: Chris@87: Chris@87: class TestRecursiveFillFields(TestCase): Chris@87: # Test recursive_fill_fields. Chris@87: def test_simple_flexible(self): Chris@87: # Test recursive_fill_fields on flexible-array Chris@87: a = np.array([(1, 10.), (2, 20.)], dtype=[('A', int), ('B', float)]) Chris@87: b = np.zeros((3,), dtype=a.dtype) Chris@87: test = recursive_fill_fields(a, b) Chris@87: control = np.array([(1, 10.), (2, 20.), (0, 0.)], Chris@87: dtype=[('A', int), ('B', float)]) Chris@87: assert_equal(test, control) Chris@87: Chris@87: def test_masked_flexible(self): Chris@87: # Test recursive_fill_fields on masked flexible-array Chris@87: a = ma.array([(1, 10.), (2, 20.)], mask=[(0, 1), (1, 0)], Chris@87: dtype=[('A', int), ('B', float)]) Chris@87: b = ma.zeros((3,), dtype=a.dtype) Chris@87: test = recursive_fill_fields(a, b) Chris@87: control = ma.array([(1, 10.), (2, 20.), (0, 0.)], Chris@87: mask=[(0, 1), (1, 0), (0, 0)], Chris@87: dtype=[('A', int), ('B', float)]) Chris@87: assert_equal(test, control) Chris@87: Chris@87: Chris@87: class TestMergeArrays(TestCase): Chris@87: # Test merge_arrays Chris@87: Chris@87: def setUp(self): Chris@87: x = np.array([1, 2, ]) Chris@87: y = np.array([10, 20, 30]) Chris@87: z = np.array( Chris@87: [('A', 1.), ('B', 2.)], dtype=[('A', '|S3'), ('B', float)]) Chris@87: w = np.array( Chris@87: [(1, (2, 3.0)), (4, (5, 6.0))], Chris@87: dtype=[('a', int), ('b', [('ba', float), ('bb', int)])]) Chris@87: self.data = (w, x, y, z) Chris@87: Chris@87: def test_solo(self): Chris@87: # Test merge_arrays on a single array. Chris@87: (_, x, _, z) = self.data Chris@87: Chris@87: test = merge_arrays(x) Chris@87: control = np.array([(1,), (2,)], dtype=[('f0', int)]) Chris@87: assert_equal(test, control) Chris@87: test = merge_arrays((x,)) Chris@87: assert_equal(test, control) Chris@87: Chris@87: test = merge_arrays(z, flatten=False) Chris@87: assert_equal(test, z) Chris@87: test = merge_arrays(z, flatten=True) Chris@87: assert_equal(test, z) Chris@87: Chris@87: def test_solo_w_flatten(self): Chris@87: # Test merge_arrays on a single array w & w/o flattening Chris@87: w = self.data[0] Chris@87: test = merge_arrays(w, flatten=False) Chris@87: assert_equal(test, w) Chris@87: Chris@87: test = merge_arrays(w, flatten=True) Chris@87: control = np.array([(1, 2, 3.0), (4, 5, 6.0)], Chris@87: dtype=[('a', int), ('ba', float), ('bb', int)]) Chris@87: assert_equal(test, control) Chris@87: Chris@87: def test_standard(self): Chris@87: # Test standard & standard Chris@87: # Test merge arrays Chris@87: (_, x, y, _) = self.data Chris@87: test = merge_arrays((x, y), usemask=False) Chris@87: control = np.array([(1, 10), (2, 20), (-1, 30)], Chris@87: dtype=[('f0', int), ('f1', int)]) Chris@87: assert_equal(test, control) Chris@87: Chris@87: test = merge_arrays((x, y), usemask=True) Chris@87: control = ma.array([(1, 10), (2, 20), (-1, 30)], Chris@87: mask=[(0, 0), (0, 0), (1, 0)], Chris@87: dtype=[('f0', int), ('f1', int)]) Chris@87: assert_equal(test, control) Chris@87: assert_equal(test.mask, control.mask) Chris@87: Chris@87: def test_flatten(self): Chris@87: # Test standard & flexible Chris@87: (_, x, _, z) = self.data Chris@87: test = merge_arrays((x, z), flatten=True) Chris@87: control = np.array([(1, 'A', 1.), (2, 'B', 2.)], Chris@87: dtype=[('f0', int), ('A', '|S3'), ('B', float)]) Chris@87: assert_equal(test, control) Chris@87: Chris@87: test = merge_arrays((x, z), flatten=False) Chris@87: control = np.array([(1, ('A', 1.)), (2, ('B', 2.))], Chris@87: dtype=[('f0', int), Chris@87: ('f1', [('A', '|S3'), ('B', float)])]) Chris@87: assert_equal(test, control) Chris@87: Chris@87: def test_flatten_wflexible(self): Chris@87: # Test flatten standard & nested Chris@87: (w, x, _, _) = self.data Chris@87: test = merge_arrays((x, w), flatten=True) Chris@87: control = np.array([(1, 1, 2, 3.0), (2, 4, 5, 6.0)], Chris@87: dtype=[('f0', int), Chris@87: ('a', int), ('ba', float), ('bb', int)]) Chris@87: assert_equal(test, control) Chris@87: Chris@87: test = merge_arrays((x, w), flatten=False) Chris@87: controldtype = [('f0', int), Chris@87: ('f1', [('a', int), Chris@87: ('b', [('ba', float), ('bb', int)])])] Chris@87: control = np.array([(1., (1, (2, 3.0))), (2, (4, (5, 6.0)))], Chris@87: dtype=controldtype) Chris@87: assert_equal(test, control) Chris@87: Chris@87: def test_wmasked_arrays(self): Chris@87: # Test merge_arrays masked arrays Chris@87: (_, x, _, _) = self.data Chris@87: mx = ma.array([1, 2, 3], mask=[1, 0, 0]) Chris@87: test = merge_arrays((x, mx), usemask=True) Chris@87: control = ma.array([(1, 1), (2, 2), (-1, 3)], Chris@87: mask=[(0, 1), (0, 0), (1, 0)], Chris@87: dtype=[('f0', int), ('f1', int)]) Chris@87: assert_equal(test, control) Chris@87: test = merge_arrays((x, mx), usemask=True, asrecarray=True) Chris@87: assert_equal(test, control) Chris@87: assert_(isinstance(test, MaskedRecords)) Chris@87: Chris@87: def test_w_singlefield(self): Chris@87: # Test single field Chris@87: test = merge_arrays((np.array([1, 2]).view([('a', int)]), Chris@87: np.array([10., 20., 30.])),) Chris@87: control = ma.array([(1, 10.), (2, 20.), (-1, 30.)], Chris@87: mask=[(0, 0), (0, 0), (1, 0)], Chris@87: dtype=[('a', int), ('f1', float)]) Chris@87: assert_equal(test, control) Chris@87: Chris@87: def test_w_shorter_flex(self): Chris@87: # Test merge_arrays w/ a shorter flexndarray. Chris@87: z = self.data[-1] Chris@87: Chris@87: # Fixme, this test looks incomplete and broken Chris@87: #test = merge_arrays((z, np.array([10, 20, 30]).view([('C', int)]))) Chris@87: #control = np.array([('A', 1., 10), ('B', 2., 20), ('-1', -1, 20)], Chris@87: # dtype=[('A', '|S3'), ('B', float), ('C', int)]) Chris@87: #assert_equal(test, control) Chris@87: Chris@87: # Hack to avoid pyflakes warnings about unused variables Chris@87: merge_arrays((z, np.array([10, 20, 30]).view([('C', int)]))) Chris@87: np.array([('A', 1., 10), ('B', 2., 20), ('-1', -1, 20)], Chris@87: dtype=[('A', '|S3'), ('B', float), ('C', int)]) Chris@87: Chris@87: def test_singlerecord(self): Chris@87: (_, x, y, z) = self.data Chris@87: test = merge_arrays((x[0], y[0], z[0]), usemask=False) Chris@87: control = np.array([(1, 10, ('A', 1))], Chris@87: dtype=[('f0', int), Chris@87: ('f1', int), Chris@87: ('f2', [('A', '|S3'), ('B', float)])]) Chris@87: assert_equal(test, control) Chris@87: Chris@87: Chris@87: class TestAppendFields(TestCase): Chris@87: # Test append_fields Chris@87: Chris@87: def setUp(self): Chris@87: x = np.array([1, 2, ]) Chris@87: y = np.array([10, 20, 30]) Chris@87: z = np.array( Chris@87: [('A', 1.), ('B', 2.)], dtype=[('A', '|S3'), ('B', float)]) Chris@87: w = np.array([(1, (2, 3.0)), (4, (5, 6.0))], Chris@87: dtype=[('a', int), ('b', [('ba', float), ('bb', int)])]) Chris@87: self.data = (w, x, y, z) Chris@87: Chris@87: def test_append_single(self): Chris@87: # Test simple case Chris@87: (_, x, _, _) = self.data Chris@87: test = append_fields(x, 'A', data=[10, 20, 30]) Chris@87: control = ma.array([(1, 10), (2, 20), (-1, 30)], Chris@87: mask=[(0, 0), (0, 0), (1, 0)], Chris@87: dtype=[('f0', int), ('A', int)],) Chris@87: assert_equal(test, control) Chris@87: Chris@87: def test_append_double(self): Chris@87: # Test simple case Chris@87: (_, x, _, _) = self.data Chris@87: test = append_fields(x, ('A', 'B'), data=[[10, 20, 30], [100, 200]]) Chris@87: control = ma.array([(1, 10, 100), (2, 20, 200), (-1, 30, -1)], Chris@87: mask=[(0, 0, 0), (0, 0, 0), (1, 0, 1)], Chris@87: dtype=[('f0', int), ('A', int), ('B', int)],) Chris@87: assert_equal(test, control) Chris@87: Chris@87: def test_append_on_flex(self): Chris@87: # Test append_fields on flexible type arrays Chris@87: z = self.data[-1] Chris@87: test = append_fields(z, 'C', data=[10, 20, 30]) Chris@87: control = ma.array([('A', 1., 10), ('B', 2., 20), (-1, -1., 30)], Chris@87: mask=[(0, 0, 0), (0, 0, 0), (1, 1, 0)], Chris@87: dtype=[('A', '|S3'), ('B', float), ('C', int)],) Chris@87: assert_equal(test, control) Chris@87: Chris@87: def test_append_on_nested(self): Chris@87: # Test append_fields on nested fields Chris@87: w = self.data[0] Chris@87: test = append_fields(w, 'C', data=[10, 20, 30]) Chris@87: control = ma.array([(1, (2, 3.0), 10), Chris@87: (4, (5, 6.0), 20), Chris@87: (-1, (-1, -1.), 30)], Chris@87: mask=[( Chris@87: 0, (0, 0), 0), (0, (0, 0), 0), (1, (1, 1), 0)], Chris@87: dtype=[('a', int), Chris@87: ('b', [('ba', float), ('bb', int)]), Chris@87: ('C', int)],) Chris@87: assert_equal(test, control) Chris@87: Chris@87: Chris@87: class TestStackArrays(TestCase): Chris@87: # Test stack_arrays Chris@87: def setUp(self): Chris@87: x = np.array([1, 2, ]) Chris@87: y = np.array([10, 20, 30]) Chris@87: z = np.array( Chris@87: [('A', 1.), ('B', 2.)], dtype=[('A', '|S3'), ('B', float)]) Chris@87: w = np.array([(1, (2, 3.0)), (4, (5, 6.0))], Chris@87: dtype=[('a', int), ('b', [('ba', float), ('bb', int)])]) Chris@87: self.data = (w, x, y, z) Chris@87: Chris@87: def test_solo(self): Chris@87: # Test stack_arrays on single arrays Chris@87: (_, x, _, _) = self.data Chris@87: test = stack_arrays((x,)) Chris@87: assert_equal(test, x) Chris@87: self.assertTrue(test is x) Chris@87: Chris@87: test = stack_arrays(x) Chris@87: assert_equal(test, x) Chris@87: self.assertTrue(test is x) Chris@87: Chris@87: def test_unnamed_fields(self): Chris@87: # Tests combinations of arrays w/o named fields Chris@87: (_, x, y, _) = self.data Chris@87: Chris@87: test = stack_arrays((x, x), usemask=False) Chris@87: control = np.array([1, 2, 1, 2]) Chris@87: assert_equal(test, control) Chris@87: Chris@87: test = stack_arrays((x, y), usemask=False) Chris@87: control = np.array([1, 2, 10, 20, 30]) Chris@87: assert_equal(test, control) Chris@87: Chris@87: test = stack_arrays((y, x), usemask=False) Chris@87: control = np.array([10, 20, 30, 1, 2]) Chris@87: assert_equal(test, control) Chris@87: Chris@87: def test_unnamed_and_named_fields(self): Chris@87: # Test combination of arrays w/ & w/o named fields Chris@87: (_, x, _, z) = self.data Chris@87: Chris@87: test = stack_arrays((x, z)) Chris@87: control = ma.array([(1, -1, -1), (2, -1, -1), Chris@87: (-1, 'A', 1), (-1, 'B', 2)], Chris@87: mask=[(0, 1, 1), (0, 1, 1), Chris@87: (1, 0, 0), (1, 0, 0)], Chris@87: dtype=[('f0', int), ('A', '|S3'), ('B', float)]) Chris@87: assert_equal(test, control) Chris@87: assert_equal(test.mask, control.mask) Chris@87: Chris@87: test = stack_arrays((z, x)) Chris@87: control = ma.array([('A', 1, -1), ('B', 2, -1), Chris@87: (-1, -1, 1), (-1, -1, 2), ], Chris@87: mask=[(0, 0, 1), (0, 0, 1), Chris@87: (1, 1, 0), (1, 1, 0)], Chris@87: dtype=[('A', '|S3'), ('B', float), ('f2', int)]) Chris@87: assert_equal(test, control) Chris@87: assert_equal(test.mask, control.mask) Chris@87: Chris@87: test = stack_arrays((z, z, x)) Chris@87: control = ma.array([('A', 1, -1), ('B', 2, -1), Chris@87: ('A', 1, -1), ('B', 2, -1), Chris@87: (-1, -1, 1), (-1, -1, 2), ], Chris@87: mask=[(0, 0, 1), (0, 0, 1), Chris@87: (0, 0, 1), (0, 0, 1), Chris@87: (1, 1, 0), (1, 1, 0)], Chris@87: dtype=[('A', '|S3'), ('B', float), ('f2', int)]) Chris@87: assert_equal(test, control) Chris@87: Chris@87: def test_matching_named_fields(self): Chris@87: # Test combination of arrays w/ matching field names Chris@87: (_, x, _, z) = self.data Chris@87: zz = np.array([('a', 10., 100.), ('b', 20., 200.), ('c', 30., 300.)], Chris@87: dtype=[('A', '|S3'), ('B', float), ('C', float)]) Chris@87: test = stack_arrays((z, zz)) Chris@87: control = ma.array([('A', 1, -1), ('B', 2, -1), Chris@87: ( Chris@87: 'a', 10., 100.), ('b', 20., 200.), ('c', 30., 300.)], Chris@87: dtype=[('A', '|S3'), ('B', float), ('C', float)], Chris@87: mask=[(0, 0, 1), (0, 0, 1), Chris@87: (0, 0, 0), (0, 0, 0), (0, 0, 0)]) Chris@87: assert_equal(test, control) Chris@87: assert_equal(test.mask, control.mask) Chris@87: Chris@87: test = stack_arrays((z, zz, x)) Chris@87: ndtype = [('A', '|S3'), ('B', float), ('C', float), ('f3', int)] Chris@87: control = ma.array([('A', 1, -1, -1), ('B', 2, -1, -1), Chris@87: ('a', 10., 100., -1), ('b', 20., 200., -1), Chris@87: ('c', 30., 300., -1), Chris@87: (-1, -1, -1, 1), (-1, -1, -1, 2)], Chris@87: dtype=ndtype, Chris@87: mask=[(0, 0, 1, 1), (0, 0, 1, 1), Chris@87: (0, 0, 0, 1), (0, 0, 0, 1), (0, 0, 0, 1), Chris@87: (1, 1, 1, 0), (1, 1, 1, 0)]) Chris@87: assert_equal(test, control) Chris@87: assert_equal(test.mask, control.mask) Chris@87: Chris@87: def test_defaults(self): Chris@87: # Test defaults: no exception raised if keys of defaults are not fields. Chris@87: (_, _, _, z) = self.data Chris@87: zz = np.array([('a', 10., 100.), ('b', 20., 200.), ('c', 30., 300.)], Chris@87: dtype=[('A', '|S3'), ('B', float), ('C', float)]) Chris@87: defaults = {'A': '???', 'B': -999., 'C': -9999., 'D': -99999.} Chris@87: test = stack_arrays((z, zz), defaults=defaults) Chris@87: control = ma.array([('A', 1, -9999.), ('B', 2, -9999.), Chris@87: ( Chris@87: 'a', 10., 100.), ('b', 20., 200.), ('c', 30., 300.)], Chris@87: dtype=[('A', '|S3'), ('B', float), ('C', float)], Chris@87: mask=[(0, 0, 1), (0, 0, 1), Chris@87: (0, 0, 0), (0, 0, 0), (0, 0, 0)]) Chris@87: assert_equal(test, control) Chris@87: assert_equal(test.data, control.data) Chris@87: assert_equal(test.mask, control.mask) Chris@87: Chris@87: def test_autoconversion(self): Chris@87: # Tests autoconversion Chris@87: adtype = [('A', int), ('B', bool), ('C', float)] Chris@87: a = ma.array([(1, 2, 3)], mask=[(0, 1, 0)], dtype=adtype) Chris@87: bdtype = [('A', int), ('B', float), ('C', float)] Chris@87: b = ma.array([(4, 5, 6)], dtype=bdtype) Chris@87: control = ma.array([(1, 2, 3), (4, 5, 6)], mask=[(0, 1, 0), (0, 0, 0)], Chris@87: dtype=bdtype) Chris@87: test = stack_arrays((a, b), autoconvert=True) Chris@87: assert_equal(test, control) Chris@87: assert_equal(test.mask, control.mask) Chris@87: try: Chris@87: test = stack_arrays((a, b), autoconvert=False) Chris@87: except TypeError: Chris@87: pass Chris@87: else: Chris@87: raise AssertionError Chris@87: Chris@87: def test_checktitles(self): Chris@87: # Test using titles in the field names Chris@87: adtype = [(('a', 'A'), int), (('b', 'B'), bool), (('c', 'C'), float)] Chris@87: a = ma.array([(1, 2, 3)], mask=[(0, 1, 0)], dtype=adtype) Chris@87: bdtype = [(('a', 'A'), int), (('b', 'B'), bool), (('c', 'C'), float)] Chris@87: b = ma.array([(4, 5, 6)], dtype=bdtype) Chris@87: test = stack_arrays((a, b)) Chris@87: control = ma.array([(1, 2, 3), (4, 5, 6)], mask=[(0, 1, 0), (0, 0, 0)], Chris@87: dtype=bdtype) Chris@87: assert_equal(test, control) Chris@87: assert_equal(test.mask, control.mask) Chris@87: Chris@87: Chris@87: class TestJoinBy(TestCase): Chris@87: def setUp(self): Chris@87: self.a = np.array(list(zip(np.arange(10), np.arange(50, 60), Chris@87: np.arange(100, 110))), Chris@87: dtype=[('a', int), ('b', int), ('c', int)]) Chris@87: self.b = np.array(list(zip(np.arange(5, 15), np.arange(65, 75), Chris@87: np.arange(100, 110))), Chris@87: dtype=[('a', int), ('b', int), ('d', int)]) Chris@87: Chris@87: def test_inner_join(self): Chris@87: # Basic test of join_by Chris@87: a, b = self.a, self.b Chris@87: Chris@87: test = join_by('a', a, b, jointype='inner') Chris@87: control = np.array([(5, 55, 65, 105, 100), (6, 56, 66, 106, 101), Chris@87: (7, 57, 67, 107, 102), (8, 58, 68, 108, 103), Chris@87: (9, 59, 69, 109, 104)], Chris@87: dtype=[('a', int), ('b1', int), ('b2', int), Chris@87: ('c', int), ('d', int)]) Chris@87: assert_equal(test, control) Chris@87: Chris@87: def test_join(self): Chris@87: a, b = self.a, self.b Chris@87: Chris@87: # Fixme, this test is broken Chris@87: #test = join_by(('a', 'b'), a, b) Chris@87: #control = np.array([(5, 55, 105, 100), (6, 56, 106, 101), Chris@87: # (7, 57, 107, 102), (8, 58, 108, 103), Chris@87: # (9, 59, 109, 104)], Chris@87: # dtype=[('a', int), ('b', int), Chris@87: # ('c', int), ('d', int)]) Chris@87: #assert_equal(test, control) Chris@87: Chris@87: # Hack to avoid pyflakes unused variable warnings Chris@87: join_by(('a', 'b'), a, b) Chris@87: np.array([(5, 55, 105, 100), (6, 56, 106, 101), Chris@87: (7, 57, 107, 102), (8, 58, 108, 103), Chris@87: (9, 59, 109, 104)], Chris@87: dtype=[('a', int), ('b', int), Chris@87: ('c', int), ('d', int)]) Chris@87: Chris@87: def test_outer_join(self): Chris@87: a, b = self.a, self.b Chris@87: Chris@87: test = join_by(('a', 'b'), a, b, 'outer') Chris@87: control = ma.array([(0, 50, 100, -1), (1, 51, 101, -1), Chris@87: (2, 52, 102, -1), (3, 53, 103, -1), Chris@87: (4, 54, 104, -1), (5, 55, 105, -1), Chris@87: (5, 65, -1, 100), (6, 56, 106, -1), Chris@87: (6, 66, -1, 101), (7, 57, 107, -1), Chris@87: (7, 67, -1, 102), (8, 58, 108, -1), Chris@87: (8, 68, -1, 103), (9, 59, 109, -1), Chris@87: (9, 69, -1, 104), (10, 70, -1, 105), Chris@87: (11, 71, -1, 106), (12, 72, -1, 107), Chris@87: (13, 73, -1, 108), (14, 74, -1, 109)], Chris@87: mask=[(0, 0, 0, 1), (0, 0, 0, 1), Chris@87: (0, 0, 0, 1), (0, 0, 0, 1), Chris@87: (0, 0, 0, 1), (0, 0, 0, 1), Chris@87: (0, 0, 1, 0), (0, 0, 0, 1), Chris@87: (0, 0, 1, 0), (0, 0, 0, 1), Chris@87: (0, 0, 1, 0), (0, 0, 0, 1), Chris@87: (0, 0, 1, 0), (0, 0, 0, 1), Chris@87: (0, 0, 1, 0), (0, 0, 1, 0), Chris@87: (0, 0, 1, 0), (0, 0, 1, 0), Chris@87: (0, 0, 1, 0), (0, 0, 1, 0)], Chris@87: dtype=[('a', int), ('b', int), Chris@87: ('c', int), ('d', int)]) Chris@87: assert_equal(test, control) Chris@87: Chris@87: def test_leftouter_join(self): Chris@87: a, b = self.a, self.b Chris@87: Chris@87: test = join_by(('a', 'b'), a, b, 'leftouter') Chris@87: control = ma.array([(0, 50, 100, -1), (1, 51, 101, -1), Chris@87: (2, 52, 102, -1), (3, 53, 103, -1), Chris@87: (4, 54, 104, -1), (5, 55, 105, -1), Chris@87: (6, 56, 106, -1), (7, 57, 107, -1), Chris@87: (8, 58, 108, -1), (9, 59, 109, -1)], Chris@87: mask=[(0, 0, 0, 1), (0, 0, 0, 1), Chris@87: (0, 0, 0, 1), (0, 0, 0, 1), Chris@87: (0, 0, 0, 1), (0, 0, 0, 1), Chris@87: (0, 0, 0, 1), (0, 0, 0, 1), Chris@87: (0, 0, 0, 1), (0, 0, 0, 1)], Chris@87: dtype=[('a', int), ('b', int), ('c', int), ('d', int)]) Chris@87: assert_equal(test, control) Chris@87: Chris@87: Chris@87: class TestJoinBy2(TestCase): Chris@87: @classmethod Chris@87: def setUp(cls): Chris@87: cls.a = np.array(list(zip(np.arange(10), np.arange(50, 60), Chris@87: np.arange(100, 110))), Chris@87: dtype=[('a', int), ('b', int), ('c', int)]) Chris@87: cls.b = np.array(list(zip(np.arange(10), np.arange(65, 75), Chris@87: np.arange(100, 110))), Chris@87: dtype=[('a', int), ('b', int), ('d', int)]) Chris@87: Chris@87: def test_no_r1postfix(self): Chris@87: # Basic test of join_by no_r1postfix Chris@87: a, b = self.a, self.b Chris@87: Chris@87: test = join_by( Chris@87: 'a', a, b, r1postfix='', r2postfix='2', jointype='inner') Chris@87: control = np.array([(0, 50, 65, 100, 100), (1, 51, 66, 101, 101), Chris@87: (2, 52, 67, 102, 102), (3, 53, 68, 103, 103), Chris@87: (4, 54, 69, 104, 104), (5, 55, 70, 105, 105), Chris@87: (6, 56, 71, 106, 106), (7, 57, 72, 107, 107), Chris@87: (8, 58, 73, 108, 108), (9, 59, 74, 109, 109)], Chris@87: dtype=[('a', int), ('b', int), ('b2', int), Chris@87: ('c', int), ('d', int)]) Chris@87: assert_equal(test, control) Chris@87: Chris@87: def test_no_postfix(self): Chris@87: self.assertRaises(ValueError, join_by, 'a', self.a, self.b, Chris@87: r1postfix='', r2postfix='') Chris@87: Chris@87: def test_no_r2postfix(self): Chris@87: # Basic test of join_by no_r2postfix Chris@87: a, b = self.a, self.b Chris@87: Chris@87: test = join_by( Chris@87: 'a', a, b, r1postfix='1', r2postfix='', jointype='inner') Chris@87: control = np.array([(0, 50, 65, 100, 100), (1, 51, 66, 101, 101), Chris@87: (2, 52, 67, 102, 102), (3, 53, 68, 103, 103), Chris@87: (4, 54, 69, 104, 104), (5, 55, 70, 105, 105), Chris@87: (6, 56, 71, 106, 106), (7, 57, 72, 107, 107), Chris@87: (8, 58, 73, 108, 108), (9, 59, 74, 109, 109)], Chris@87: dtype=[('a', int), ('b1', int), ('b', int), Chris@87: ('c', int), ('d', int)]) Chris@87: assert_equal(test, control) Chris@87: Chris@87: def test_two_keys_two_vars(self): Chris@87: a = np.array(list(zip(np.tile([10, 11], 5), np.repeat(np.arange(5), 2), Chris@87: np.arange(50, 60), np.arange(10, 20))), Chris@87: dtype=[('k', int), ('a', int), ('b', int), ('c', int)]) Chris@87: Chris@87: b = np.array(list(zip(np.tile([10, 11], 5), np.repeat(np.arange(5), 2), Chris@87: np.arange(65, 75), np.arange(0, 10))), Chris@87: dtype=[('k', int), ('a', int), ('b', int), ('c', int)]) Chris@87: Chris@87: control = np.array([(10, 0, 50, 65, 10, 0), (11, 0, 51, 66, 11, 1), Chris@87: (10, 1, 52, 67, 12, 2), (11, 1, 53, 68, 13, 3), Chris@87: (10, 2, 54, 69, 14, 4), (11, 2, 55, 70, 15, 5), Chris@87: (10, 3, 56, 71, 16, 6), (11, 3, 57, 72, 17, 7), Chris@87: (10, 4, 58, 73, 18, 8), (11, 4, 59, 74, 19, 9)], Chris@87: dtype=[('k', int), ('a', int), ('b1', int), Chris@87: ('b2', int), ('c1', int), ('c2', int)]) Chris@87: test = join_by( Chris@87: ['a', 'k'], a, b, r1postfix='1', r2postfix='2', jointype='inner') Chris@87: assert_equal(test.dtype, control.dtype) Chris@87: assert_equal(test, control) Chris@87: Chris@87: Chris@87: if __name__ == '__main__': Chris@87: run_module_suite()