From 79a7f3ec804fd57410a5655ab05941885354e5e7 Mon Sep 17 00:00:00 2001 From: Jeff Reback Date: Mon, 15 Oct 2012 22:21:44 -0400 Subject: [PATCH] a panel constructed with a None value throws an error (0.9 exhibits the same behavior) Python 2.7.3 (default, Jun 21 2012, 07:50:29) [GCC 4.4.5] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import pandas >>> print pandas.__version__ 0.8.1 >>> print pandas.Panel(dict(a = None, b = pandas.DataFrame(index=[1,2,3],columns=[1,2,3]))) Traceback (most recent call last): File "", line 1, in File "/usr/local/lib/python2.7/site-packages/pandas-0.8.1-py2.7-linux-x86_64.egg/pandas/core/panel.py", line 219, in __init__ mgr = self._init_dict(data, passed_axes, dtype=dtype) File "/usr/local/lib/python2.7/site-packages/pandas-0.8.1-py2.7-linux-x86_64.egg/pandas/core/panel.py", line 256, in _init_dict major = _extract_axis(data, axis=0) File "/usr/local/lib/python2.7/site-packages/pandas-0.8.1-py2.7-linux-x86_64.egg/pandas/core/panel.py", line 1396, in _extract_axis raw_lengths.append(v.shape[axis]) AttributeError: 'NoneType' object has no attribute 'shape' added tests and fixes for this case (and the pathological case of constructing with dict(a=None)) --- pandas/core/panel.py | 14 ++++++++++---- pandas/tests/test_panel.py | 10 ++++++++-- 2 files changed, 18 insertions(+), 6 deletions(-) mode change 100644 => 100755 pandas/core/panel.py mode change 100644 => 100755 pandas/tests/test_panel.py diff --git a/pandas/core/panel.py b/pandas/core/panel.py old mode 100644 new mode 100755 index 211434ab07154..b802a7f86731b --- a/pandas/core/panel.py +++ b/pandas/core/panel.py @@ -1403,8 +1403,11 @@ def _homogenize_dict(frames, intersect=True, dtype=None): columns = _extract_axis(adj_frames, axis=1, intersect=intersect) for key, frame in adj_frames.iteritems(): - result[key] = frame.reindex(index=index, columns=columns, - copy=False) + if frame is not None: + result[key] = frame.reindex(index=index, columns=columns, + copy=False) + else: + result[key] = None return result, index, columns @@ -1415,7 +1418,7 @@ def _extract_axis(data, axis=0, intersect=False): elif len(data) > 0: raw_lengths = [] indexes = [] - + index = None have_raw_arrays = False have_frames = False @@ -1423,7 +1426,7 @@ def _extract_axis(data, axis=0, intersect=False): if isinstance(v, DataFrame): have_frames = True indexes.append(v._get_axis(axis)) - else: + elif v is not None: have_raw_arrays = True raw_lengths.append(v.shape[axis]) @@ -1440,6 +1443,9 @@ def _extract_axis(data, axis=0, intersect=False): else: index = Index(np.arange(lengths[0])) + if index is None: + index = Index([]) + return _ensure_index(index) diff --git a/pandas/tests/test_panel.py b/pandas/tests/test_panel.py old mode 100644 new mode 100755 index 36e667322fa9d..1cf4e73e25b3f --- a/pandas/tests/test_panel.py +++ b/pandas/tests/test_panel.py @@ -730,8 +730,9 @@ def test_ctor_dict(self): d = {'A' : itema, 'B' : itemb[5:]} d2 = {'A' : itema._series, 'B' : itemb[5:]._series} - d3 = {'A' : DataFrame(itema._series), - 'B' : DataFrame(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 @@ -748,6 +749,11 @@ def test_ctor_dict(self): 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 } + wp4 = Panel.from_dict(d4) + assert_panel_equal(Panel(d4), Panel(items = ['A','B'])) + # cast dcasted = dict((k, v.reindex(wp.major_axis).fillna(0)) for k, v in d.iteritems())