def test_concatenate(self): values = np.arange(12).reshape(3, 4) ax1 = Index("year", [2014, 2015, 2016]) ax2 = Index("month", ["jan", "feb", "mar", "apr"]) c = Cube([ax1, ax2],values) values = np.arange(12).reshape(4, 3) ax3 = Index("year", [2014, 2015, 2016]) ax4 = Index("month", ["may", "jun", "jul", "aug"]) d = Cube([ax4, ax3],values) e = concatenate([c, d], "month") self.assertEqual(e.ndim, 2) self.assertEqual(e.shape, (8, 3)) # the joined axis is always the first self.assertTrue(is_axis(e.axis("month"))) e = concatenate([c, d], "month", as_index=True) self.assertEqual(e.ndim, 2) self.assertEqual(e.shape, (8, 3)) self.assertTrue(is_indexed(e.axis("month"))) # duplicate index values self.assertRaises(ValueError, concatenate, [c, c], "month", as_index=True) # broadcasting of an axis countries = Axis("country", ["DE", "FR"]) f = d.insert_axis(countries) g = concatenate([c, f], "month", broadcast=True) self.assertEqual(g.ndim, 3) self.assertEqual(g.shape, (8, 3, 2)) # if automatic broadcasting is not allowed self.assertRaises(LookupError, concatenate, [c, f], "month", broadcast=False)
def test_empty_cube(self): c = Cube(Axis("x", []),[] ) self.assertEqual(c.ndim, 1) self.assertEqual(c.dims, ("x",)) self.assertEqual(c.size, 0) c = Cube( [Axis("x", []), Axis("y", [])],np.empty((0, 0))) self.assertEqual(c.ndim, 2) self.assertEqual(c.dims, ("x", "y")) self.assertEqual(c.size, 0)
def test_create_scalar(self): c = Cube(None,1 ) self.assertEqual(c.ndim, 0) self.assertEqual(c.size, 1) c = Cube(None, None) self.assertEqual(c.ndim, 0) self.assertEqual(c.size, 1) c = Cube([],1) self.assertEqual(c.ndim, 0) self.assertEqual(c.size, 1)
def year_quarter_weekday_cube(): """Creates 3D cube with axes "year", "quarter", "weekday" with shape (3, 4, 7).""" values = np.arange(3 * 4 * 7).reshape(3, 4, 7) ax1 = Index("year", [2014, 2015, 2016]) ax2 = Index("quarter", ["Q1", "Q2", "Q3", "Q4"]) ax3 = Index("weekday", ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]) return Cube([ax1, ax2, ax3],values)
def test_filter(self): """Testing function Cube.filter()""" c = year_quarter_cube() d = c.filter("year", [2014, 2018]) # 2018 is ignored self.assertEqual(d.ndim, 2) self.assertTrue((d.values == c.values[0]).all()) year_filter = Axis("year", range(2010, 2015)) d = c.filter(year_filter) self.assertEqual(d.ndim, 2) self.assertTrue((d.values == c.values[0]).all()) year_filter = Index("year", range(2010, 2015)) d = c.filter(year_filter) self.assertEqual(d.ndim, 2) self.assertTrue((d.values == c.values[0]).all()) country_filter = Axis("country", ["DE", "FR"]) # this axis is ignored # filter by two axis filters quarter_filter = Index("quarter", ["Q1", "Q3"]) d = c.filter([quarter_filter, country_filter, year_filter]) self.assertEqual(d.ndim, 2) self.assertTrue((d.values == c.values[[0, 0], [0, 2]]).all()) # cube as a filter yq_cube_filter = Cube.ones([quarter_filter, year_filter, country_filter]) d = c.filter(yq_cube_filter) self.assertEqual(d.ndim, 2) self.assertTrue((d.values == c.values[[0, 0], [0, 2]]).all()) # a collection of cubes as a filter y_cube_filter = Cube.ones([year_filter, country_filter]) q_cube_filter = Cube.ones([country_filter, quarter_filter]) d = c.filter([y_cube_filter, q_cube_filter]) self.assertEqual(d.ndim, 2) self.assertTrue((d.values == c.values[[0, 0], [0, 2]]).all())
def test_squeeze(self): """Removes axes which have only one element.""" ax1 = Index("A", [1]) # has only one element, thus can be collapsed ax2 = Index("B", [1, 2, 3]) c = Cube([ax1, ax2],[[1, 2, 3]] ) self.assertEqual(c.ndim, 2) d = c.squeeze() self.assertEqual(d.ndim, 1) self.assertEqual(d.axis(0).name, "B") c = Cube([ax2, ax1],[[1], [2], [3]]) self.assertEqual(c.ndim, 2) d = c.squeeze() self.assertEqual(d.ndim, 1) self.assertEqual(d.axis(0).name, "B") ax3 = Index("C", [1]) # has only one element, thus can be collapsed c = Cube([ax1, ax3],[[1]]) self.assertEqual(c.ndim, 2) d = c.squeeze() # will collapse both axes self.assertEqual(d.ndim, 0)
def test_group_by(self): values = np.arange(12).reshape(3, 4) ax1 = Axis("year", [2014, 2014, 2014]) ax2 = Axis("month", ["jan", "jan", "feb", "feb"]) c = Cube([ax1, ax2],values) d = c.reduce(np.mean, group=0) # average by year self.assertTrue(np.array_equal(d.values, np.array([[4, 5, 6, 7]]))) self.assertTrue(is_indexed(d.axis(0))) self.assertEqual(len(d.axis(0)), 1) self.assertEqual(d.values.shape, (1, 4)) # axes with length of 1 are not collapsed d = c.reduce(np.sum, group=ax2.name, sort_grp=False) # sum by month self.assertTrue(np.array_equal(d.values, np.array([[1, 5], [9, 13], [17, 21]]))) self.assertTrue(np.array_equal(d.axis(ax2.name).values, ["jan", "feb"])) d = c.reduce(np.sum, group=ax2.name) # sum by month, sorted by default self.assertTrue(np.array_equal(d.values, np.array([[5, 1], [13, 9], [21, 17]]))) self.assertTrue(np.array_equal(d.axis(ax2.name).values, ["feb", "jan"])) self.assertTrue(is_indexed(d.axis(ax2.name))) self.assertEqual(len(d.axis(ax2.name)), 2) self.assertEqual(d.values.shape, (3, 2)) # testing various aggregation functions using direct calling, e.g. c.sum(group=0), # or indirect calling, e.g. reduce(func=np.sum, group=0) funcs_indirect = [np.sum, np.mean, np.median, np.min, np.max, np.prod] funcs_direct = [c.sum, c.mean, c.median, c.min, c.max, c.prod] for func_indirect, func_direct in zip(funcs_indirect, funcs_direct): result = np.apply_along_axis(func_indirect, 0, c.values) d = c.reduce(func_indirect, group=ax1.name) self.assertTrue(np.array_equiv(d.values, result)) e = func_direct(group=ax1.name) self.assertTrue(np.array_equiv(e.values, result)) # testing function with extra parameters which cannot be passed as *args third_quartile = functools.partial(np.percentile, q=75) d = c.reduce(third_quartile, group=ax1.name) self.assertTrue(np.array_equiv(d.values, np.apply_along_axis(third_quartile, 0, c.values))) # the same but using lambda - this is actually simpler and more powerful way third_quartile_lambda = lambda sample: np.percentile(sample, q=75) d = c.reduce(third_quartile_lambda, group=ax1.name) self.assertTrue(np.array_equiv(d.values, np.apply_along_axis(third_quartile_lambda, 0, c.values)))
def test_create_cube(self): ax1 = Index("A", [10, 20, 30]) ax2 = Index("B", ["a", "b", "c", "d"]) ax3 = Index("C", [1.1, 1.2]) # test Cube.zeros() a = Cube.zeros([ax1, ax3]) self.assertTrue(np.array_equal(a.values, [[0, 0], [0, 0], [0, 0]])) # test Cube.ones() a = Cube.ones([ax1, ax3]) self.assertTrue(np.array_equal(a.values, [[1, 1], [1, 1], [1, 1]])) # test Cube.full() a = Cube.full([ax1, ax3], np.inf) self.assertTrue(np.array_equal(a.values, [[np.inf, np.inf], [np.inf, np.inf], [np.inf, np.inf]])) # test Cube.full with NaNs # note: be careful because NaN != NaN so np.array_equal does not work a = Cube.full([ax1, ax3], np.nan) np.testing.assert_equal(a.values, [[np.nan, np.nan], [np.nan, np.nan], [np.nan, np.nan]]) # create one-dimensional cube values = np.arange(3) try: Cube((ax1,),values) Cube(ax1,values) # no need to pass axes as collection if there is only one axis except Exception: self.fail("raised exception unexpectedly") # two-dimensional cubes values = np.arange(12).reshape(3, 4) try: Cube((ax1, ax2),values) Cube([ax1, ax2],values) except Exception: self.fail("raised exception unexpectedly")
def year_quarter_cube(): """Creates a sample 2D cube with axes "year" and "quarter" with shape (3, 4).""" values = np.arange(12).reshape(3, 4) ax1 = Index("year", [2014, 2015, 2016]) ax2 = Index("quarter", ["Q1", "Q2", "Q3", "Q4"]) return Cube([ax1, ax2],values)
def test_operations(self): values = np.arange(12).reshape(3, 4) axc1 = Index("a", [10, 20, 30]) axc2 = Index("b", ["a", "b", "c", "d"]) c = Cube([axc1, axc2],values) axd1 = Index("a", [10, 20, 30]) axd2 = Index("b", ["a", "b", "c", "d"]) d = Cube([axd1, axd2],values) x = c * d self.assertTrue(np.array_equal(x.values, values * values)) e = Cube([Index("a", [10, 20, 30])],[0, 1, 2]) x2 = c * e self.assertTrue(np.array_equal(x2.values, values * np.array([[0], [1], [2]]))) c3 = Cube([Index("b", ["a", "b", "c", "d"])],[0, 1, 2, 3]) x3 = c * c3 self.assertTrue(np.array_equal(x3.values, values * np.array([0, 1, 2, 3]))) c3 = Cube([Index("b", ["b", "a", "c", "d"])],[0, 1, 2, 3]) x3 = c * c3 self.assertTrue(np.array_equal(x3.values, values * np.array([1, 0, 2, 3]))) values_d = np.array([0, 1]) d = Cube([Index("d", ["d1", "d2"])],values_d) x = c * d self.assertEqual(x.ndim, 3) self.assertEqual(x.axis(0).name, "a") self.assertEqual(x.axis(1).name, "b") self.assertEqual(x.axis(2).name, "d") self.assertTrue(np.array_equal(x.values, values.reshape(3, 4, 1) * values_d)) # operations with scalar d = 10 x = c * d self.assertTrue(np.array_equal(x.values, values * d)) x = d * c self.assertTrue(np.array_equal(x.values, values * d)) # operations with numpy.ndarray d = np.arange(4) x = c * d self.assertTrue(np.array_equal(x.values, values * d)) x = d * c self.assertTrue(np.array_equal(x.values, values * d)) d = np.arange(3).reshape(3, 1) x = c * d self.assertTrue(np.array_equal(x.values, values * d)) x = d * c self.assertTrue(np.array_equal(x.values, values * d)) # matching Index and Series values_d = np.array([0, 1]) d = Cube(Axis("a", [10, 10]),values_d) x = c * d self.assertTrue(np.array_equal(x.values, values.take([0, 0], 0) * values_d[:, np.newaxis])) values_d = np.array([0, 1, 2, 3]) d = Cube(Axis("b", ["d", "d", "c", "a"]),values_d) x = c * d self.assertTrue(np.array_equal(x.values, values.take([3, 3, 2, 0], 1) * values_d)) # unary plus and minus c = year_quarter_cube() self.assertTrue(np.array_equal((+c).values, c.values)) self.assertTrue(np.array_equal((-c).values, -c.values)) c = year_quarter_cube() + 1 # +1 to prevent division by zero error import operator as op ops = [op.add, op.mul, op.floordiv, op.truediv, op.sub, op.pow, op.mod, # arithmetics ops op.eq, op.ne, op.ge, op.le, op.gt, op.lt, # comparison ops op.rshift, op.lshift] # bitwise ops # operations with scalar d = 2 for op in ops: self.assertTrue(np.array_equal(op(c, d).values, op(c.values, d))) self.assertTrue(np.array_equal(op(d, c).values, op(d, c.values))) # oprations with numpy array d = (np.arange(12).reshape(3, 4) / 6 + 1).astype(np.int) # +1 to prevent division by zero error for op in ops: self.assertTrue(np.array_equal(op(c, d).values, op(c.values, d))) self.assertTrue(np.array_equal(op(d, c).values, op(d, c.values)))