/pandas/tests/test_panel.py
Python | 2558 lines | 1827 code | 557 blank | 174 comment | 96 complexity | 2ade495abdddf1bddcae962754764de4 MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0
Large files files are truncated, but you can click here to view the full file
- # -*- coding: utf-8 -*-
- # pylint: disable=W0612,E1101
- from datetime import datetime
- import operator
- import nose
- import numpy as np
- import pandas as pd
- from pandas.types.common import is_float_dtype
- from pandas import Series, DataFrame, Index, isnull, notnull, pivot, MultiIndex
- from pandas.core.datetools import bday
- from pandas.core.nanops import nanall, nanany
- from pandas.core.panel import Panel
- from pandas.core.series import remove_na
- from pandas.formats.printing import pprint_thing
- from pandas import compat
- from pandas.compat import range, lrange, StringIO, OrderedDict, signature
- from pandas.util.testing import (assert_panel_equal, assert_frame_equal,
- assert_series_equal, assert_almost_equal,
- ensure_clean, assertRaisesRegexp,
- makeCustomDataframe as mkdf,
- makeMixedDataFrame)
- import pandas.core.panel as panelm
- import pandas.util.testing as tm
- class PanelTests(object):
- panel = None
- def test_pickle(self):
- unpickled = self.round_trip_pickle(self.panel)
- assert_frame_equal(unpickled['ItemA'], self.panel['ItemA'])
- def test_rank(self):
- self.assertRaises(NotImplementedError, lambda: self.panel.rank())
- def test_cumsum(self):
- cumsum = self.panel.cumsum()
- assert_frame_equal(cumsum['ItemA'], self.panel['ItemA'].cumsum())
- def not_hashable(self):
- c_empty = Panel()
- c = Panel(Panel([[[1]]]))
- self.assertRaises(TypeError, hash, c_empty)
- self.assertRaises(TypeError, hash, c)
- class SafeForLongAndSparse(object):
- _multiprocess_can_split_ = True
- def test_repr(self):
- repr(self.panel)
- def test_copy_names(self):
- for attr in ('major_axis', 'minor_axis'):
- getattr(self.panel, attr).name = None
- cp = self.panel.copy()
- getattr(cp, attr).name = 'foo'
- self.assertIsNone(getattr(self.panel, attr).name)
- def test_iter(self):
- tm.equalContents(list(self.panel), self.panel.items)
- def test_count(self):
- f = lambda s: notnull(s).sum()
- self._check_stat_op('count', f, obj=self.panel, has_skipna=False)
- def test_sum(self):
- self._check_stat_op('sum', np.sum)
- def test_mean(self):
- self._check_stat_op('mean', np.mean)
- def test_prod(self):
- self._check_stat_op('prod', np.prod)
- def test_median(self):
- def wrapper(x):
- if isnull(x).any():
- return np.nan
- return np.median(x)
- self._check_stat_op('median', wrapper)
- def test_min(self):
- self._check_stat_op('min', np.min)
- def test_max(self):
- self._check_stat_op('max', np.max)
- def test_skew(self):
- try:
- from scipy.stats import skew
- except ImportError:
- raise nose.SkipTest("no scipy.stats.skew")
- def this_skew(x):
- if len(x) < 3:
- return np.nan
- return skew(x, bias=False)
- self._check_stat_op('skew', this_skew)
- # def test_mad(self):
- # f = lambda x: np.abs(x - x.mean()).mean()
- # self._check_stat_op('mad', f)
- def test_var(self):
- def alt(x):
- if len(x) < 2:
- return np.nan
- return np.var(x, ddof=1)
- self._check_stat_op('var', alt)
- def test_std(self):
- def alt(x):
- if len(x) < 2:
- return np.nan
- return np.std(x, ddof=1)
- self._check_stat_op('std', alt)
- def test_sem(self):
- def alt(x):
- if len(x) < 2:
- return np.nan
- return np.std(x, ddof=1) / np.sqrt(len(x))
- self._check_stat_op('sem', alt)
- def _check_stat_op(self, name, alternative, obj=None, has_skipna=True):
- if obj is None:
- obj = self.panel
- # # set some NAs
- # obj.ix[5:10] = np.nan
- # obj.ix[15:20, -2:] = np.nan
- f = getattr(obj, name)
- if has_skipna:
- def skipna_wrapper(x):
- nona = remove_na(x)
- if len(nona) == 0:
- return np.nan
- return alternative(nona)
- def wrapper(x):
- return alternative(np.asarray(x))
- for i in range(obj.ndim):
- result = f(axis=i, skipna=False)
- assert_frame_equal(result, obj.apply(wrapper, axis=i))
- else:
- skipna_wrapper = alternative
- wrapper = alternative
- for i in range(obj.ndim):
- result = f(axis=i)
- if not tm._incompat_bottleneck_version(name):
- assert_frame_equal(result, obj.apply(skipna_wrapper, axis=i))
- self.assertRaises(Exception, f, axis=obj.ndim)
- # Unimplemented numeric_only parameter.
- if 'numeric_only' in signature(f).args:
- self.assertRaisesRegexp(NotImplementedError, name, f,
- numeric_only=True)
- class SafeForSparse(object):
- _multiprocess_can_split_ = True
- @classmethod
- def assert_panel_equal(cls, x, y):
- assert_panel_equal(x, y)
- def test_get_axis(self):
- assert (self.panel._get_axis(0) is self.panel.items)
- assert (self.panel._get_axis(1) is self.panel.major_axis)
- assert (self.panel._get_axis(2) is self.panel.minor_axis)
- def test_set_axis(self):
- new_items = Index(np.arange(len(self.panel.items)))
- new_major = Index(np.arange(len(self.panel.major_axis)))
- new_minor = Index(np.arange(len(self.panel.minor_axis)))
- # ensure propagate to potentially prior-cached items too
- item = self.panel['ItemA']
- self.panel.items = new_items
- if hasattr(self.panel, '_item_cache'):
- self.assertNotIn('ItemA', self.panel._item_cache)
- self.assertIs(self.panel.items, new_items)
- # TODO: unused?
- item = self.panel[0] # noqa
- self.panel.major_axis = new_major
- self.assertIs(self.panel[0].index, new_major)
- self.assertIs(self.panel.major_axis, new_major)
- # TODO: unused?
- item = self.panel[0] # noqa
- self.panel.minor_axis = new_minor
- self.assertIs(self.panel[0].columns, new_minor)
- self.assertIs(self.panel.minor_axis, new_minor)
- def test_get_axis_number(self):
- self.assertEqual(self.panel._get_axis_number('items'), 0)
- self.assertEqual(self.panel._get_axis_number('major'), 1)
- self.assertEqual(self.panel._get_axis_number('minor'), 2)
- with tm.assertRaisesRegexp(ValueError, "No axis named foo"):
- self.panel._get_axis_number('foo')
- with tm.assertRaisesRegexp(ValueError, "No axis named foo"):
- self.panel.__ge__(self.panel, axis='foo')
- def test_get_axis_name(self):
- self.assertEqual(self.panel._get_axis_name(0), 'items')
- self.assertEqual(self.panel._get_axis_name(1), 'major_axis')
- self.assertEqual(self.panel._get_axis_name(2), 'minor_axis')
- def test_get_plane_axes(self):
- # what to do here?
- index, columns = self.panel._get_plane_axes('items')
- index, columns = self.panel._get_plane_axes('major_axis')
- index, columns = self.panel._get_plane_axes('minor_axis')
- index, columns = self.panel._get_plane_axes(0)
- def test_truncate(self):
- dates = self.panel.major_axis
- start, end = dates[1], dates[5]
- trunced = self.panel.truncate(start, end, axis='major')
- expected = self.panel['ItemA'].truncate(start, end)
- assert_frame_equal(trunced['ItemA'], expected)
- trunced = self.panel.truncate(before=start, axis='major')
- expected = self.panel['ItemA'].truncate(before=start)
- assert_frame_equal(trunced['ItemA'], expected)
- trunced = self.panel.truncate(after=end, axis='major')
- expected = self.panel['ItemA'].truncate(after=end)
- assert_frame_equal(trunced['ItemA'], expected)
- # XXX test other axes
- def test_arith(self):
- self._test_op(self.panel, operator.add)
- self._test_op(self.panel, operator.sub)
- self._test_op(self.panel, operator.mul)
- self._test_op(self.panel, operator.truediv)
- self._test_op(self.panel, operator.floordiv)
- self._test_op(self.panel, operator.pow)
- self._test_op(self.panel, lambda x, y: y + x)
- self._test_op(self.panel, lambda x, y: y - x)
- self._test_op(self.panel, lambda x, y: y * x)
- self._test_op(self.panel, lambda x, y: y / x)
- self._test_op(self.panel, lambda x, y: y ** x)
- self._test_op(self.panel, lambda x, y: x + y) # panel + 1
- self._test_op(self.panel, lambda x, y: x - y) # panel - 1
- self._test_op(self.panel, lambda x, y: x * y) # panel * 1
- self._test_op(self.panel, lambda x, y: x / y) # panel / 1
- self._test_op(self.panel, lambda x, y: x ** y) # panel ** 1
- self.assertRaises(Exception, self.panel.__add__, self.panel['ItemA'])
- @staticmethod
- def _test_op(panel, op):
- result = op(panel, 1)
- assert_frame_equal(result['ItemA'], op(panel['ItemA'], 1))
- def test_keys(self):
- tm.equalContents(list(self.panel.keys()), self.panel.items)
- def test_iteritems(self):
- # Test panel.iteritems(), aka panel.iteritems()
- # just test that it works
- for k, v in self.panel.iteritems():
- pass
- self.assertEqual(len(list(self.panel.iteritems())),
- len(self.panel.items))
- def test_combineFrame(self):
- def check_op(op, name):
- # items
- df = self.panel['ItemA']
- func = getattr(self.panel, name)
- result = func(df, axis='items')
- assert_frame_equal(result['ItemB'], op(self.panel['ItemB'], df))
- # major
- xs = self.panel.major_xs(self.panel.major_axis[0])
- result = func(xs, axis='major')
- idx = self.panel.major_axis[1]
- assert_frame_equal(result.major_xs(idx),
- op(self.panel.major_xs(idx), xs))
- # minor
- xs = self.panel.minor_xs(self.panel.minor_axis[0])
- result = func(xs, axis='minor')
- idx = self.panel.minor_axis[1]
- assert_frame_equal(result.minor_xs(idx),
- op(self.panel.minor_xs(idx), xs))
- ops = ['add', 'sub', 'mul', 'truediv', 'floordiv', 'pow', 'mod']
- if not compat.PY3:
- ops.append('div')
- for op in ops:
- try:
- check_op(getattr(operator, op), op)
- except:
- pprint_thing("Failing operation: %r" % op)
- raise
- if compat.PY3:
- try:
- check_op(operator.truediv, 'div')
- except:
- pprint_thing("Failing operation: %r" % 'div')
- raise
- def test_combinePanel(self):
- result = self.panel.add(self.panel)
- self.assert_panel_equal(result, self.panel * 2)
- def test_neg(self):
- self.assert_panel_equal(-self.panel, self.panel * -1)
- # issue 7692
- def test_raise_when_not_implemented(self):
- p = Panel(np.arange(3 * 4 * 5).reshape(3, 4, 5),
- items=['ItemA', 'ItemB', 'ItemC'],
- major_axis=pd.date_range('20130101', periods=4),
- minor_axis=list('ABCDE'))
- d = p.sum(axis=1).ix[0]
- ops = ['add', 'sub', 'mul', 'truediv', 'floordiv', 'div', 'mod', 'pow']
- for op in ops:
- with self.assertRaises(NotImplementedError):
- getattr(p, op)(d, axis=0)
- def test_select(self):
- p = self.panel
- # select items
- result = p.select(lambda x: x in ('ItemA', 'ItemC'), axis='items')
- expected = p.reindex(items=['ItemA', 'ItemC'])
- self.assert_panel_equal(result, expected)
- # select major_axis
- result = p.select(lambda x: x >= datetime(2000, 1, 15), axis='major')
- new_major = p.major_axis[p.major_axis >= datetime(2000, 1, 15)]
- expected = p.reindex(major=new_major)
- self.assert_panel_equal(result, expected)
- # select minor_axis
- result = p.select(lambda x: x in ('D', 'A'), axis=2)
- expected = p.reindex(minor=['A', 'D'])
- self.assert_panel_equal(result, expected)
- # corner case, empty thing
- result = p.select(lambda x: x in ('foo', ), axis='items')
- self.assert_panel_equal(result, p.reindex(items=[]))
- def test_get_value(self):
- for item in self.panel.items:
- for mjr in self.panel.major_axis[::2]:
- for mnr in self.panel.minor_axis:
- result = self.panel.get_value(item, mjr, mnr)
- expected = self.panel[item][mnr][mjr]
- assert_almost_equal(result, expected)
- def test_abs(self):
- result = self.panel.abs()
- result2 = abs(self.panel)
- expected = np.abs(self.panel)
- self.assert_panel_equal(result, expected)
- self.assert_panel_equal(result2, expected)
- df = self.panel['ItemA']
- result = df.abs()
- result2 = abs(df)
- expected = np.abs(df)
- assert_frame_equal(result, expected)
- assert_frame_equal(result2, expected)
- s = df['A']
- result = s.abs()
- result2 = abs(s)
- expected = np.abs(s)
- assert_series_equal(result, expected)
- assert_series_equal(result2, expected)
- self.assertEqual(result.name, 'A')
- self.assertEqual(result2.name, 'A')
- class CheckIndexing(object):
- _multiprocess_can_split_ = True
- def test_getitem(self):
- self.assertRaises(Exception, self.panel.__getitem__, 'ItemQ')
- def test_delitem_and_pop(self):
- expected = self.panel['ItemA']
- result = self.panel.pop('ItemA')
- assert_frame_equal(expected, result)
- self.assertNotIn('ItemA', self.panel.items)
- del self.panel['ItemB']
- self.assertNotIn('ItemB', self.panel.items)
- self.assertRaises(Exception, self.panel.__delitem__, 'ItemB')
- values = np.empty((3, 3, 3))
- values[0] = 0
- values[1] = 1
- values[2] = 2
- panel = Panel(values, lrange(3), lrange(3), lrange(3))
- # did we delete the right row?
- panelc = panel.copy()
- del panelc[0]
- assert_frame_equal(panelc[1], panel[1])
- assert_frame_equal(panelc[2], panel[2])
- panelc = panel.copy()
- del panelc[1]
- assert_frame_equal(panelc[0], panel[0])
- assert_frame_equal(panelc[2], panel[2])
- panelc = panel.copy()
- del panelc[2]
- assert_frame_equal(panelc[1], panel[1])
- assert_frame_equal(panelc[0], panel[0])
- def test_setitem(self):
- # LongPanel with one item
- lp = self.panel.filter(['ItemA', 'ItemB']).to_frame()
- with tm.assertRaises(ValueError):
- self.panel['ItemE'] = lp
- # DataFrame
- df = self.panel['ItemA'][2:].filter(items=['A', 'B'])
- self.panel['ItemF'] = df
- self.panel['ItemE'] = df
- df2 = self.panel['ItemF']
- assert_frame_equal(df, df2.reindex(index=df.index, columns=df.columns))
- # scalar
- self.panel['ItemG'] = 1
- self.panel['ItemE'] = True
- self.assertEqual(self.panel['ItemG'].values.dtype, np.int64)
- self.assertEqual(self.panel['ItemE'].values.dtype, np.bool_)
- # object dtype
- self.panel['ItemQ'] = 'foo'
- self.assertEqual(self.panel['ItemQ'].values.dtype, np.object_)
- # boolean dtype
- self.panel['ItemP'] = self.panel['ItemA'] > 0
- self.assertEqual(self.panel['ItemP'].values.dtype, np.bool_)
- self.assertRaises(TypeError, self.panel.__setitem__, 'foo',
- self.panel.ix[['ItemP']])
- # bad shape
- p = Panel(np.random.randn(4, 3, 2))
- with tm.assertRaisesRegexp(ValueError,
- "shape of value must be \(3, 2\), "
- "shape of given object was \(4, 2\)"):
- p[0] = np.random.randn(4, 2)
- def test_setitem_ndarray(self):
- from pandas import date_range, datetools
- timeidx = date_range(start=datetime(2009, 1, 1),
- end=datetime(2009, 12, 31),
- freq=datetools.MonthEnd())
- lons_coarse = np.linspace(-177.5, 177.5, 72)
- lats_coarse = np.linspace(-87.5, 87.5, 36)
- P = Panel(items=timeidx, major_axis=lons_coarse,
- minor_axis=lats_coarse)
- data = np.random.randn(72 * 36).reshape((72, 36))
- key = datetime(2009, 2, 28)
- P[key] = data
- assert_almost_equal(P[key].values, data)
- def test_set_minor_major(self):
- # GH 11014
- df1 = DataFrame(['a', 'a', 'a', np.nan, 'a', np.nan])
- df2 = DataFrame([1.0, np.nan, 1.0, np.nan, 1.0, 1.0])
- panel = Panel({'Item1': df1, 'Item2': df2})
- newminor = notnull(panel.iloc[:, :, 0])
- panel.loc[:, :, 'NewMinor'] = newminor
- assert_frame_equal(panel.loc[:, :, 'NewMinor'],
- newminor.astype(object))
- newmajor = notnull(panel.iloc[:, 0, :])
- panel.loc[:, 'NewMajor', :] = newmajor
- assert_frame_equal(panel.loc[:, 'NewMajor', :],
- newmajor.astype(object))
- def test_major_xs(self):
- ref = self.panel['ItemA']
- idx = self.panel.major_axis[5]
- xs = self.panel.major_xs(idx)
- result = xs['ItemA']
- assert_series_equal(result, ref.xs(idx), check_names=False)
- self.assertEqual(result.name, 'ItemA')
- # not contained
- idx = self.panel.major_axis[0] - bday
- self.assertRaises(Exception, self.panel.major_xs, idx)
- def test_major_xs_mixed(self):
- self.panel['ItemD'] = 'foo'
- xs = self.panel.major_xs(self.panel.major_axis[0])
- self.assertEqual(xs['ItemA'].dtype, np.float64)
- self.assertEqual(xs['ItemD'].dtype, np.object_)
- def test_minor_xs(self):
- ref = self.panel['ItemA']
- idx = self.panel.minor_axis[1]
- xs = self.panel.minor_xs(idx)
- assert_series_equal(xs['ItemA'], ref[idx], check_names=False)
- # not contained
- self.assertRaises(Exception, self.panel.minor_xs, 'E')
- def test_minor_xs_mixed(self):
- self.panel['ItemD'] = 'foo'
- xs = self.panel.minor_xs('D')
- self.assertEqual(xs['ItemA'].dtype, np.float64)
- self.assertEqual(xs['ItemD'].dtype, np.object_)
- def test_xs(self):
- itemA = self.panel.xs('ItemA', axis=0)
- expected = self.panel['ItemA']
- assert_frame_equal(itemA, expected)
- # get a view by default
- itemA_view = self.panel.xs('ItemA', axis=0)
- itemA_view.values[:] = np.nan
- self.assertTrue(np.isnan(self.panel['ItemA'].values).all())
- # mixed-type yields a copy
- self.panel['strings'] = 'foo'
- result = self.panel.xs('D', axis=2)
- self.assertIsNotNone(result.is_copy)
- def test_getitem_fancy_labels(self):
- p = self.panel
- items = p.items[[1, 0]]
- dates = p.major_axis[::2]
- cols = ['D', 'C', 'F']
- # all 3 specified
- assert_panel_equal(p.ix[items, dates, cols],
- p.reindex(items=items, major=dates, minor=cols))
- # 2 specified
- assert_panel_equal(p.ix[:, dates, cols],
- p.reindex(major=dates, minor=cols))
- assert_panel_equal(p.ix[items, :, cols],
- p.reindex(items=items, minor=cols))
- assert_panel_equal(p.ix[items, dates, :],
- p.reindex(items=items, major=dates))
- # only 1
- assert_panel_equal(p.ix[items, :, :], p.reindex(items=items))
- assert_panel_equal(p.ix[:, dates, :], p.reindex(major=dates))
- assert_panel_equal(p.ix[:, :, cols], p.reindex(minor=cols))
- def test_getitem_fancy_slice(self):
- pass
- def test_getitem_fancy_ints(self):
- p = self.panel
- # #1603
- result = p.ix[:, -1, :]
- expected = p.ix[:, p.major_axis[-1], :]
- assert_frame_equal(result, expected)
- def test_getitem_fancy_xs(self):
- p = self.panel
- item = 'ItemB'
- date = p.major_axis[5]
- col = 'C'
- # get DataFrame
- # item
- assert_frame_equal(p.ix[item], p[item])
- assert_frame_equal(p.ix[item, :], p[item])
- assert_frame_equal(p.ix[item, :, :], p[item])
- # major axis, axis=1
- assert_frame_equal(p.ix[:, date], p.major_xs(date))
- assert_frame_equal(p.ix[:, date, :], p.major_xs(date))
- # minor axis, axis=2
- assert_frame_equal(p.ix[:, :, 'C'], p.minor_xs('C'))
- # get Series
- assert_series_equal(p.ix[item, date], p[item].ix[date])
- assert_series_equal(p.ix[item, date, :], p[item].ix[date])
- assert_series_equal(p.ix[item, :, col], p[item][col])
- assert_series_equal(p.ix[:, date, col], p.major_xs(date).ix[col])
- def test_getitem_fancy_xs_check_view(self):
- item = 'ItemB'
- date = self.panel.major_axis[5]
- # make sure it's always a view
- NS = slice(None, None)
- # DataFrames
- comp = assert_frame_equal
- self._check_view(item, comp)
- self._check_view((item, NS), comp)
- self._check_view((item, NS, NS), comp)
- self._check_view((NS, date), comp)
- self._check_view((NS, date, NS), comp)
- self._check_view((NS, NS, 'C'), comp)
- # Series
- comp = assert_series_equal
- self._check_view((item, date), comp)
- self._check_view((item, date, NS), comp)
- self._check_view((item, NS, 'C'), comp)
- self._check_view((NS, date, 'C'), comp)
- def test_getitem_callable(self):
- p = self.panel
- # GH 12533
- assert_frame_equal(p[lambda x: 'ItemB'], p.loc['ItemB'])
- assert_panel_equal(p[lambda x: ['ItemB', 'ItemC']],
- p.loc[['ItemB', 'ItemC']])
- def test_ix_setitem_slice_dataframe(self):
- a = Panel(items=[1, 2, 3], major_axis=[11, 22, 33],
- minor_axis=[111, 222, 333])
- b = DataFrame(np.random.randn(2, 3), index=[111, 333],
- columns=[1, 2, 3])
- a.ix[:, 22, [111, 333]] = b
- assert_frame_equal(a.ix[:, 22, [111, 333]], b)
- def test_ix_align(self):
- from pandas import Series
- b = Series(np.random.randn(10), name=0)
- b.sort()
- df_orig = Panel(np.random.randn(3, 10, 2))
- df = df_orig.copy()
- df.ix[0, :, 0] = b
- assert_series_equal(df.ix[0, :, 0].reindex(b.index), b)
- df = df_orig.swapaxes(0, 1)
- df.ix[:, 0, 0] = b
- assert_series_equal(df.ix[:, 0, 0].reindex(b.index), b)
- df = df_orig.swapaxes(1, 2)
- df.ix[0, 0, :] = b
- assert_series_equal(df.ix[0, 0, :].reindex(b.index), b)
- def test_ix_frame_align(self):
- p_orig = tm.makePanel()
- df = p_orig.ix[0].copy()
- assert_frame_equal(p_orig['ItemA'], df)
- p = p_orig.copy()
- p.ix[0, :, :] = df
- assert_panel_equal(p, p_orig)
- p = p_orig.copy()
- p.ix[0] = df
- assert_panel_equal(p, p_orig)
- p = p_orig.copy()
- p.iloc[0, :, :] = df
- assert_panel_equal(p, p_orig)
- p = p_orig.copy()
- p.iloc[0] = df
- assert_panel_equal(p, p_orig)
- p = p_orig.copy()
- p.loc['ItemA'] = df
- assert_panel_equal(p, p_orig)
- p = p_orig.copy()
- p.loc['ItemA', :, :] = df
- assert_panel_equal(p, p_orig)
- p = p_orig.copy()
- p['ItemA'] = df
- assert_panel_equal(p, p_orig)
- p = p_orig.copy()
- p.ix[0, [0, 1, 3, 5], -2:] = df
- out = p.ix[0, [0, 1, 3, 5], -2:]
- assert_frame_equal(out, df.iloc[[0, 1, 3, 5], [2, 3]])
- # GH3830, panel assignent by values/frame
- for dtype in ['float64', 'int64']:
- panel = Panel(np.arange(40).reshape((2, 4, 5)),
- items=['a1', 'a2'], dtype=dtype)
- df1 = panel.iloc[0]
- df2 = panel.iloc[1]
- tm.assert_frame_equal(panel.loc['a1'], df1)
- tm.assert_frame_equal(panel.loc['a2'], df2)
- # Assignment by Value Passes for 'a2'
- panel.loc['a2'] = df1.values
- tm.assert_frame_equal(panel.loc['a1'], df1)
- tm.assert_frame_equal(panel.loc['a2'], df1)
- # Assignment by DataFrame Ok w/o loc 'a2'
- panel['a2'] = df2
- tm.assert_frame_equal(panel.loc['a1'], df1)
- tm.assert_frame_equal(panel.loc['a2'], df2)
- # Assignment by DataFrame Fails for 'a2'
- panel.loc['a2'] = df2
- tm.assert_frame_equal(panel.loc['a1'], df1)
- tm.assert_frame_equal(panel.loc['a2'], df2)
- def _check_view(self, indexer, comp):
- cp = self.panel.copy()
- obj = cp.ix[indexer]
- obj.values[:] = 0
- self.assertTrue((obj.values == 0).all())
- comp(cp.ix[indexer].reindex_like(obj), obj)
- def test_logical_with_nas(self):
- d = Panel({'ItemA': {'a': [np.nan, False]},
- 'ItemB': {'a': [True, True]}})
- result = d['ItemA'] | d['ItemB']
- expected = DataFrame({'a': [np.nan, True]})
- assert_frame_equal(result, expected)
- # this is autodowncasted here
- result = d['ItemA'].fillna(False) | d['ItemB']
- expected = DataFrame({'a': [True, True]})
- assert_frame_equal(result, expected)
- def test_neg(self):
- # what to do?
- assert_panel_equal(-self.panel, -1 * self.panel)
- def test_invert(self):
- assert_panel_equal(-(self.panel < 0), ~(self.panel < 0))
- def test_comparisons(self):
- p1 = tm.makePanel()
- p2 = tm.makePanel()
- tp = p1.reindex(items=p1.items + ['foo'])
- df = p1[p1.items[0]]
- def test_comp(func):
- # versus same index
- result = func(p1, p2)
- self.assert_numpy_array_equal(result.values,
- func(p1.values, p2.values))
- # versus non-indexed same objs
- self.assertRaises(Exception, func, p1, tp)
- # versus different objs
- self.assertRaises(Exception, func, p1, df)
- # versus scalar
- result3 = func(self.panel, 0)
- self.assert_numpy_array_equal(result3.values,
- func(self.panel.values, 0))
- test_comp(operator.eq)
- test_comp(operator.ne)
- test_comp(operator.lt)
- test_comp(operator.gt)
- test_comp(operator.ge)
- test_comp(operator.le)
- def test_get_value(self):
- for item in self.panel.items:
- for mjr in self.panel.major_axis[::2]:
- for mnr in self.panel.minor_axis:
- result = self.panel.get_value(item, mjr, mnr)
- expected = self.panel[item][mnr][mjr]
- assert_almost_equal(result, expected)
- with tm.assertRaisesRegexp(TypeError,
- "There must be an argument for each axis"):
- self.panel.get_value('a')
- def test_set_value(self):
- for item in self.panel.items:
- for mjr in self.panel.major_axis[::2]:
- for mnr in self.panel.minor_axis:
- self.panel.set_value(item, mjr, mnr, 1.)
- assert_almost_equal(self.panel[item][mnr][mjr], 1.)
- # resize
- res = self.panel.set_value('ItemE', 'foo', 'bar', 1.5)
- tm.assertIsInstance(res, Panel)
- self.assertIsNot(res, self.panel)
- self.assertEqual(res.get_value('ItemE', 'foo', 'bar'), 1.5)
- res3 = self.panel.set_value('ItemE', 'foobar', 'baz', 5)
- self.assertTrue(is_float_dtype(res3['ItemE'].values))
- with tm.assertRaisesRegexp(TypeError,
- "There must be an argument for each axis"
- " plus the value provided"):
- self.panel.set_value('a')
- _panel = tm.makePanel()
- tm.add_nans(_panel)
- class TestPanel(tm.TestCase, PanelTests, CheckIndexing, SafeForLongAndSparse,
- SafeForSparse):
- _multiprocess_can_split_ = True
- @classmethod
- def assert_panel_equal(cls, x, y):
- assert_panel_equal(x, y)
- def setUp(self):
- self.panel = _panel.copy()
- self.panel.major_axis.name = None
- self.panel.minor_axis.name = None
- self.panel.items.name = None
- def test_panel_warnings(self):
- with tm.assert_produces_warning(FutureWarning):
- shifted1 = self.panel.shift(lags=1)
- with tm.assert_produces_warning(False):
- shifted2 = self.panel.shift(periods=1)
- tm.assert_panel_equal(shifted1, shifted2)
- with tm.assert_produces_warning(False):
- shifted3 = self.panel.shift()
- tm.assert_panel_equal(shifted1, shifted3)
- def test_constructor(self):
- # with BlockManager
- wp = Panel(self.panel._data)
- self.assertIs(wp._data, self.panel._data)
- wp = Panel(self.panel._data, copy=True)
- self.assertIsNot(wp._data, self.panel._data)
- assert_panel_equal(wp, self.panel)
- # strings handled prop
- wp = Panel([[['foo', 'foo', 'foo', ], ['foo', 'foo', 'foo']]])
- self.assertEqual(wp.values.dtype, np.object_)
- vals = self.panel.values
- # no copy
- wp = Panel(vals)
- self.assertIs(wp.values, vals)
- # copy
- wp = Panel(vals, copy=True)
- self.assertIsNot(wp.values, vals)
- # GH #8285, test when scalar data is used to construct a Panel
- # if dtype is not passed, it should be inferred
- value_and_dtype = [(1, 'int64'), (3.14, 'float64'),
- ('foo', np.object_)]
- for (val, dtype) in value_and_dtype:
- wp = Panel(val, items=range(2), major_axis=range(3),
- minor_axis=range(4))
- vals = np.empty((2, 3, 4), dtype=dtype)
- vals.fill(val)
- assert_panel_equal(wp, Panel(vals, dtype=dtype))
- # test the case when dtype is passed
- wp = Panel(1, items=range(2), major_axis=range(3), minor_axis=range(4),
- dtype='float32')
- vals = np.empty((2, 3, 4), dtype='float32')
- vals.fill(1)
- assert_panel_equal(wp, Panel(vals, dtype='float32'))
- def test_constructor_cast(self):
- zero_filled = self.panel.fillna(0)
- casted = Panel(zero_filled._data, dtype=int)
- casted2 = Panel(zero_filled.values, dtype=int)
- exp_values = zero_filled.values.astype(int)
- assert_almost_equal(casted.values, exp_values)
- assert_almost_equal(casted2.values, exp_values)
- casted = Panel(zero_filled._data, dtype=np.int32)
- casted2 = Panel(zero_filled.values, dtype=np.int32)
- exp_values = zero_filled.values.astype(np.int32)
- assert_almost_equal(casted.values, exp_values)
- assert_almost_equal(casted2.values, exp_values)
- # can't cast
- data = [[['foo', 'bar', 'baz']]]
- self.assertRaises(ValueError, Panel, data, dtype=float)
- def test_constructor_empty_panel(self):
- empty = Panel()
- self.assertEqual(len(empty.items), 0)
- self.assertEqual(len(empty.major_axis), 0)
- self.assertEqual(len(empty.minor_axis), 0)
- def test_constructor_observe_dtype(self):
- # GH #411
- panel = Panel(items=lrange(3), major_axis=lrange(3),
- minor_axis=lrange(3), dtype='O')
- self.assertEqual(panel.values.dtype, np.object_)
- def test_constructor_dtypes(self):
- # GH #797
- def _check_dtype(panel, dtype):
- for i in panel.items:
- self.assertEqual(panel[i].values.dtype.name, dtype)
- # only nan holding types allowed here
- for dtype in ['float64', 'float32', 'object']:
- panel = Panel(items=lrange(2), major_axis=lrange(10),
- minor_axis=lrange(5), dtype=dtype)
- _check_dtype(panel, dtype)
- for dtype in ['float64', 'float32', 'int64', 'int32', 'object']:
- panel = Panel(np.array(np.random.randn(2, 10, 5), dtype=dtype),
- items=lrange(2),
- major_axis=lrange(10),
- minor_axis=lrange(5), dtype=dtype)
- _check_dtype(panel, dtype)
- for dtype in ['float64', 'float32', 'int64', 'int32', 'object']:
- panel = Panel(np.array(np.random.randn(2, 10, 5), dtype='O'),
- items=lrange(2),
- major_axis=lrange(10),
- minor_axis=lrange(5), dtype=dtype)
- _check_dtype(panel, dtype)
- for dtype in ['float64', 'float32', 'int64', 'int32', 'object']:
- panel = Panel(np.random.randn(2, 10, 5), items=lrange(
- 2), major_axis=lrange(10), minor_axis=lrange(5), dtype=dtype)
- _check_dtype(panel, dtype)
- for dtype in ['float64', 'float32', 'int64', 'int32', 'object']:
- df1 = DataFrame(np.random.randn(2, 5),
- index=lrange(2), columns=lrange(5))
- df2 = DataFrame(np.random.randn(2, 5),
- index=lrange(2), columns=lrange(5))
- panel = Panel.from_dict({'a': df1, 'b': df2}, dtype=dtype)
- _check_dtype(panel, dtype)
- def test_constructor_fails_with_not_3d_input(self):
- with tm.assertRaisesRegexp(ValueError,
- "The number of dimensions required is 3"):
- Panel(np.random.randn(10, 2))
- def test_consolidate(self):
- self.assertTrue(self.panel._data.is_consolidated())
- self.panel['foo'] = 1.
- self.assertFalse(self.panel._data.is_consolidated())
- panel = self.panel.consolidate()
- self.assertTrue(panel._data.is_consolidated())
- def test_ctor_dict(self):
- itema = self.panel['ItemA']
- itemb = self.panel['ItemB']
- d = {'A': itema, 'B': itemb[5:]}
- d2 = {'A': itema._series, 'B': itemb[5:]._series}
- d3 = {'A': None,
- 'B': DataFrame(itemb[5:]._series),
- 'C': DataFrame(itema._series)}
- wp = Panel.from_dict(d)
- wp2 = Panel.from_dict(d2) # nested Dict
- # TODO: unused?
- wp3 = Panel.from_dict(d3) # noqa
- self.assert_index_equal(wp.major_axis, self.panel.major_axis)
- assert_panel_equal(wp, wp2)
- # intersect
- wp = Panel.from_dict(d, intersect=True)
- self.assert_index_equal(wp.major_axis, itemb.index[5:])
- # use constructor
- assert_panel_equal(Panel(d), Panel.from_dict(d))
- assert_panel_equal(Panel(d2), Panel.from_dict(d2))
- assert_panel_equal(Panel(d3), Panel.from_dict(d3))
- # a pathological case
- d4 = {'A': None, 'B': None}
- # TODO: unused?
- wp4 = Panel.from_dict(d4) # noqa
- assert_panel_equal(Panel(d4), Panel(items=['A', 'B']))
- # cast
- dcasted = dict((k, v.reindex(wp.major_axis).fillna(0))
- for k, v in compat.iteritems(d))
- result = Panel(dcasted, dtype=int)
- expected = Panel(dict((k, v.astype(int))
- for k, v in compat.iteritems(dcasted)))
- assert_panel_equal(result, expected)
- result = Panel(dcasted, dtype=np.int32)
- expected = Panel(dict((k, v.astype(np.int32))
- for k, v in compat.iteritems(dcasted)))
- assert_panel_equal(result, expected)
- def test_constructor_dict_mixed(self):
- data = dict((k, v.values) for k, v in self.panel.iteritems())
- result = Panel(data)
- exp_major = Index(np.arange(len(self.panel.major_axis)))
- self.assert_index_equal(result.major_axis, exp_major)
- result = Panel(data, items=self.panel.items,
- major_axis=self.panel.major_axis,
- minor_axis=self.panel.minor_axis)
- assert_panel_equal(result, self.panel)
- data['ItemC'] = self.panel['ItemC']
- result = Panel(data)
- assert_panel_equal(result, self.panel)
- # corner, blow up
- data['ItemB'] = data['ItemB'][:-1]
- self.assertRaises(Exception, Panel, data)
- data['ItemB'] = self.panel['ItemB'].values[:, :-1]
- self.assertRaises(Exception, Panel, data)
- def test_ctor_orderedDict(self):
- keys = list(set(np.random.randint(0, 5000, 100)))[
- :50] # unique random int keys
- d = OrderedDict([(k, mkdf(10, 5)) for k in keys])
- p = Panel(d)
- self.assertTrue(list(p.items) == keys)
- p = Panel.from_dict(d)
- self.assertTrue(list(p.items) == keys)
- def test_constructor_resize(self):
- data = self.panel._data
- items = self.panel.items[:-1]
- major = self.panel.major_axis[:-1]
- minor = self.panel.minor_axis[:-1]
- result = Panel(data, items=items, major_axis=major, minor_axis=minor)
- expected = self.panel.reindex(items=items, major=major, minor=minor)
- assert_panel_equal(result, expected)
- result = Panel(data, items=items, major_axis=major)
- expected = self.panel.reindex(items=items, major=major)
- assert_panel_equal(result, expected)
- result = Panel(data, items=items)
- expected = self.panel.reindex(items=items)
- assert_panel_equal(result, expected)
- result = Panel(data, minor_axis=minor)
- expected = self.panel.reindex(minor=minor)
- assert_panel_equal(result, expected)
- def test_from_dict_mixed_orient(self):
- df = tm.makeDataFrame()
- df['foo'] = 'bar'
- data = {'k1': df, 'k2': df}
- panel = Panel.from_dict(data, orient='minor')
- self.assertEqual(panel['foo'].values.dtype, np.object_)
- self.assertEqual(panel['A'].values.dtype, np.float64)
- def test_constructor_error_msgs(self):
- def testit():
- Panel(np.random.randn(3, 4, 5), lrange(4), lrange(5), lrange(5))
- assertRaisesRegexp(ValueError,
- "Shape of passed values is \(3, 4, 5\), "
- "indices imply \(4, 5, 5\)",
- testit)
- def testit():
- Panel(np.random.randn(3, 4, 5), lrange(5), lrange(4), lrange(5))
- assertRaisesRegexp(ValueError,
- "Shape of passed values is \(3, 4, 5\), "
- "indices imply \(5, 4, 5\)",
- testit)
- def testit():
- Panel(np.random.randn(3, 4, 5), lrange(5), lrange(5), lrange(4))
- assertRaisesRegexp(ValueError,
- "Shape of passed values is \(3, 4, 5\), "
- "indices imply \(5, 5, 4\)",
- testit)
- def test_conform(self):
- df = self.panel['ItemA'][:-5].filter(items=['A', 'B'])
- conformed = self.panel.conform(df)
- tm.assert_index_equal(conformed.index, self.panel.major_axis)
- tm.assert_index_equal(conformed.columns, self.panel.minor_axis)
- def test_convert_objects(self):
- # GH 4937
- p = Panel(dict(A=dict(a=['1', '1.0'])))
- expected = Panel(dict(A=dict(a=[1, 1.0])))
- result = p._convert(numeric=True, coerce=True)
- assert_panel_equal(result, expected)
- def test_dtypes(self):
- result = self.panel.dtypes
- expected = Series(np.dtype('float64'), index=self.panel.items)
- assert_series_equal(result, expected)
- def test_astype(self):
- # GH7271
- data = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
- panel = Panel(data, ['a', 'b'], ['c', 'd'], ['e', 'f'])
- str_data = np.array([[['1', '2'], ['3', '4']],
- [['5', '6'], ['7', '8']]])
- expected = Panel(str_data, ['a', 'b'], ['c', 'd'], ['e', 'f'])
- assert_panel_equal(panel.astype(str), expected)
- self.assertRaises(NotImplementedError, panel.astype, {0: str})
- def test_apply(self):
- # GH1148
- # ufunc
- applied = self.panel.apply(np.sqrt)
- self.assertTrue(assert_almost_equal(applied.values, np.sqrt(
- self.panel.values)))
- # ufunc same shape
- result = self.panel.apply(lambda x: x * 2, axis='items')
- expected = self.panel * 2
- assert_panel_equal(result, expected)
- result = self.panel.apply(lambda x: x * 2, axis='major_axis')
- expected = self.panel * 2
- assert_panel_equal(result, expected)
- result = self.panel.apply(lambda x: x * 2, axis='minor_axis')
- expected = self.panel * 2
- assert_panel_equal(result, expected)
- # reduction to DataFrame
- result = self.panel.apply(lambda x: x.dtype, axis='items')
- expected = DataFrame(np.dtype('float64'), index=self.panel.major_axis,
- columns=self.panel.minor_axis)
- assert_frame_equal(result, expected)
- result = self.panel.apply(lambda x: x.dtype, axis='major_axis')
- expected = DataFrame(np.dtype('float64'), index=self.panel.minor_axis,
- columns=self.panel.items)
- assert_frame_equal(result, expected)
- result = self.panel.apply(lambda x: x.dtype, axis='minor_axis')
- expected = DataFrame(np.dtype('float64'), index=self.panel.major_axis,
- columns=self.panel.items)
- assert_frame_equal(result, expected)
- # reductions via other dims
- expected = self.panel.sum(0)
- result = self.panel.apply(lambda x: x.sum(), axis='items')
- assert_frame_equal(result, expected)
- expected = self.panel.sum(1)
- result = self.panel.apply(lambda x: x.sum(), axis='major_axis')
- assert_frame_equal(result, expected)
- expected = self.panel.sum(2)
- result = self.panel.apply(lambda x: x.sum(), axis='minor_axis')
- assert_frame_equal(result, expected)
- # pass kwargs
- result = self.panel.apply(lambda x, y: x.sum() + y, axis='items', y=5)
- expected = self.panel.sum(0) + 5
- assert_frame_equal(result, expected)
- def test_apply_slabs(self):
- # same shape as original
- result = self.panel.apply(lambda x: x * 2,
- axis=['items', 'major_axis'])
- expected = (self.panel * 2).transpose('minor_axis', 'major_axis',
- 'items')
- assert_panel_equal(result, expected)
- result = self.panel.apply(lambda x: x * 2,
- axis=['major_axis', 'items'])
- assert_panel_equal(result, expected)
- result = self.panel.apply(lambda x: x * 2,
- axis=['items', 'minor_axis'])
- expected = (self.panel * 2).transpose('major_axis', 'minor_axis',
- 'items')
- assert_panel_equal(result, expected)
- result = self.panel.apply(lambda x: x * 2,
- axis=['minor_axis', 'items'])
- assert_panel_equal(result, expected)
- result = self.panel.apply(lambda x: x * 2,
- axis=['major_axis', 'minor_axis'])
- expected = self.panel * 2
- assert_panel_equal(result, expected)
- result = self.panel.apply(lambda x: x * 2,
- axis=['minor_axis', 'major_axis'])
- assert_panel_equal(result, expected)
- # reductions
- result = self.panel.apply(lambda x: x.sum(0), axis=[
- 'items', 'major_axis'
- ])
- expected = self.panel.sum(1).T
- assert_frame_equal(result, expected)
- result = self.panel.apply(lambda x: x.sum(1), axis=[
- 'items', 'major_axis'
- ])
- expected = self.panel.sum(0)
- assert_frame_equal(result, expected)
- # transforms
- f = lambda x: ((x.T - x.mean(1)) / x.std(1)).T
- # make sure that we don't trigger any warnings
- with tm.assert_produces_warning(False):
- result = self.panel.apply(f, axis=['items', 'major_axis'])
- expected = Panel(dict([(ax, f(self.panel.loc[:, :, ax]))
- for ax in self.panel.minor_axis]))
- assert_panel_equal(result, expected)
- result = self.panel.apply(f, axis=['major_axis', 'minor_axis'])
- expected = Panel(dict([(ax, f(self.panel.loc[ax]))
- for ax in self.panel.items]))
- assert_panel_equal(result, expected)
- result = self.panel.apply(f, axis=['minor_axis', 'items'])
- expected = Panel(dict([(ax, f(self.panel.loc[:, ax]))
- for ax in self.panel.major_axis]))
- assert_panel_equal(result, expected)
- # with multi-indexes
- # GH7469
- index = MultiIndex.from_tuples([('one', 'a'), ('one', 'b'), (
- 'two', 'a'), ('two', 'b')])
- dfa = DataFrame(np.array(np.arange(12, dtype='int64')).reshape(
- 4, 3), columns=list("ABC"), index=index)
- dfb = DataFrame(np.array(np.arange(10, 22, dtype='int64')).reshape(
- 4, 3), columns=list("ABC"), index=index)
- p = Panel({'f': dfa, 'g': dfb})
- result = p.apply(lambda x: x.sum(), axis=0)
- # on windows this will be in32
- result = result.astype('int64')
- expected = p.sum(0)
- assert_frame_equal(result, expected)
- def test_apply_no_or_zero_ndim(self):
- # GH10332
- self.panel = Panel(np.random.rand(5, 5, 5))
- result_int = self.panel.apply(lambda df: 0, axis=[1, 2])
- result_float = self.panel.apply(lambda df: 0.0, axis=[1, 2])
- result_int64 = self.panel.apply(lambda df: np.int64(0), axis=[1, 2])
- result_float64 = self.panel.apply(lambda df: np.float64(0.0),
- axis=[1, 2])
- expected_int = expected_int64 = Series([0] * 5)
- expected_float = expected_float64 = Series([0.0] * 5)
- assert_series_equal(result_int, expected_int)
- assert_series_equal(result_int64, expected_int64)
- assert_series_equal(result_float, expected_float)
- assert_series_equal(result_float64, expected_float64)
- def test_reindex(self):
- ref = self.panel['ItemB']
- # items
- result = self.panel.reindex(items=['ItemA', 'ItemB'])
- assert_frame_equal(result['ItemB'], ref)
- # major
- new_major = list(self.panel.major_axis[:10])
- result = self.panel.reindex(major=new_major)
- assert_frame_equal(result['ItemB'], ref.reindex(index=new_major))
- # raise exception put both major and major_axis
- self.assertRaises(Exception, self.panel.reindex, major_axis=new_major,
- major=new_major)
- # minor
- new_minor = list(self.panel.minor_axis[:2])
- result = self.panel.reindex(minor=new_minor)
- assert_frame_equal(result['ItemB'], ref.reindex(columns=new_minor))
- # this ok
- result = self.panel.reindex()
- assert_panel_equal(result, self.panel)
- self.assertFalse(result is self.panel)
- # with filling
- smaller_major = self.panel.major_axis[::5]
- smaller = self.panel.reindex(major=smaller_major)
- larger = smaller.reindex(major=self.panel.major_axis, method='pad')
- assert_frame_equal(larger.major_xs(self.panel.major_axis[1]),
- smaller.major_xs(smaller_major[0]))
- # don't necessarily copy
- result = self.panel.reindex(major=self.panel.major_axis, copy=False)
- assert_panel_equal(result, self.panel)
- self.assertTrue(result is self.panel)
- def test_reindex_multi(self):
- # with and without copy full reindexing
- result = self.panel.reindex(items=self.panel.items,
- major=self.panel.major_axis,
- minor=self.panel.minor_axis, copy=False)
- self.assertIs(result.items, self.panel.items)
- self.assertIs(result.major_axis, self.panel.major_axis)
- self.assertIs(result.minor_axis, self.panel.minor_axis)
- result = self.panel.reindex(items=self.panel.items,
- major=self.panel.major_axis,
- minor=self.panel.minor_axis, copy=False)
- assert_panel_equal(result, self.panel)
- # multi-axis indexing consistency
- # GH 5900
- df = DataFrame(np.random.randn(4, 3))
- p = Panel({'Item1': df})
- expected = Panel({'Item1': df})
- expected['Item2'] = np.nan
- items = ['Item1', 'Item2']
- major_axis = np.arange(4)
- minor_axis = np.arange(3)
- results = []
- results.append(p.reindex(items=items, major_axis=major_axis,
- copy=True))
- results.append(p.reindex(items=items, major_axis=major_axis,
- copy=False))
- results.append(p.reindex(items=items, minor_axis=minor_axis,
- copy=True))
- results.append(p.reindex(items=items, minor_axis=minor_axis,
- copy=False))
- results.append(p.reindex(items=items, major_axis=major_axis,
- minor_axis=minor_axis, copy=True))
- results.append(p.reindex(items=items, major_axis=major_axis,
- …
Large files files are truncated, but you can click here to view the full file