diff --git a/doc/source/whatsnew/v0.16.0.txt b/doc/source/whatsnew/v0.16.0.txt index d60fa718ae07c..5b2a788829ce3 100644 --- a/doc/source/whatsnew/v0.16.0.txt +++ b/doc/source/whatsnew/v0.16.0.txt @@ -622,3 +622,4 @@ Bug Fixes - Bug in ``Series.values_counts`` with excluding ``NaN`` for categorical type ``Series`` with ``dropna=True`` (:issue:`9443`) - Fixed mising numeric_only option for ``DataFrame.std/var/sem`` (:issue:`9201`) +- Support constructing ``Panel`` or ``Panel4D`` with scalar data (:issue:`8285`) diff --git a/pandas/core/panel.py b/pandas/core/panel.py index b3fc9aec00271..7df23a54c737d 100644 --- a/pandas/core/panel.py +++ b/pandas/core/panel.py @@ -165,6 +165,13 @@ def _init_data(self, data, copy, dtype, **kwargs): mgr = self._init_matrix(data, passed_axes, dtype=dtype, copy=copy) copy = False dtype = None + elif lib.isscalar(data) and all(x is not None for x in passed_axes): + if dtype is None: + dtype, data = _infer_dtype_from_scalar(data) + values = np.empty([len(x) for x in passed_axes], dtype=dtype) + values.fill(data) + mgr = self._init_matrix(values, passed_axes, dtype=dtype, copy=False) + copy = False else: # pragma: no cover raise PandasError('Panel constructor not properly called!') diff --git a/pandas/tests/test_panel.py b/pandas/tests/test_panel.py index 744dd31755c81..841df36fa0a84 100644 --- a/pandas/tests/test_panel.py +++ b/pandas/tests/test_panel.py @@ -888,6 +888,21 @@ def test_constructor(self): 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, int), (3.14, float), ('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=float) + vals = np.empty((2, 3, 4), dtype=float) + vals.fill(1) + assert_panel_equal(wp, Panel(vals, dtype=float)) + def test_constructor_cast(self): zero_filled = self.panel.fillna(0) diff --git a/pandas/tests/test_panel4d.py b/pandas/tests/test_panel4d.py index 94c6bb9e2a4aa..7d6332879cfb4 100644 --- a/pandas/tests/test_panel4d.py +++ b/pandas/tests/test_panel4d.py @@ -629,6 +629,21 @@ def test_constructor(self): panel4d = Panel4D(vals, copy=True) self.assertIsNot(panel4d.values, vals) + # GH #8285, test when scalar data is used to construct a Panel4D + # if dtype is not passed, it should be inferred + value_and_dtype = [(1, int), (3.14, float), ('foo', np.object_)] + for (val, dtype) in value_and_dtype: + panel4d = Panel4D(val, labels=range(2), items=range(3), major_axis=range(4), minor_axis=range(5)) + vals = np.empty((2, 3, 4, 5), dtype=dtype) + vals.fill(val) + assert_panel4d_equal(panel4d, Panel4D(vals, dtype=dtype)) + + # test the case when dtype is passed + panel4d = Panel4D(1, labels=range(2), items=range(3), major_axis=range(4), minor_axis=range(5), dtype=float) + vals = np.empty((2, 3, 4, 5), dtype=float) + vals.fill(1) + assert_panel4d_equal(panel4d, Panel4D(vals, dtype=float)) + def test_constructor_cast(self): zero_filled = self.panel4d.fillna(0)