Skip to content

BUG/Not Implemented Panel.to_frame() with MultiIndex #5402

Closed
@TomAugspurger

Description

@TomAugspurger

Should this be doable?

In [39]: df = pd.DataFrame({'A': [1, 2], 'B': pd.to_datetime(['a', 'b'])},
                  index=pd.MultiIndex.from_tuples([(1, 'one'), (1, 'two')]))

In [40]: df
Out[40]: 
       A  B
1 one  1  a
  two  2  b

In [41]: wp = pd.Panel({'i1': df, 'i2': df})

In [42]: wp.to_frame()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-42-e49d9f2f9609> in <module>()
----> 1 wp.to_frame()

/Users/tom/Envs/pandas-dev/lib/python2.7/site-packages/pandas-0.12.0_993_gda89834-py2.7-macosx-10.8-x86_64.egg/pandas/core/panel.pyc in to_frame(self, filter_observations)
    846         index = MultiIndex(levels=[self.major_axis, self.minor_axis],
    847                            labels=[major_labels, minor_labels],
--> 848                            names=[maj_name, min_name], verify_integrity=False)
    849 
    850         return DataFrame(data, index=index, columns=self.items)

/Users/tom/Envs/pandas-dev/lib/python2.7/site-packages/pandas-0.12.0_993_gda89834-py2.7-macosx-10.8-x86_64.egg/pandas/core/index.pyc in __new__(cls, levels, labels, sortorder, names, copy, verify_integrity)
   1880         if names is not None:
   1881             # handles name validation
-> 1882             subarr._set_names(names)
   1883 
   1884         if sortorder is not None:

/Users/tom/Envs/pandas-dev/lib/python2.7/site-packages/pandas-0.12.0_993_gda89834-py2.7-macosx-10.8-x86_64.egg/pandas/core/index.pyc in _set_names(self, values, validate)
   2150         # set the name
   2151         for name, level in zip(values, self.levels):
-> 2152             level.rename(name, inplace=True)
   2153 
   2154     names = property(

/Users/tom/Envs/pandas-dev/lib/python2.7/site-packages/pandas-0.12.0_993_gda89834-py2.7-macosx-10.8-x86_64.egg/pandas/core/index.pyc in set_names(self, names, inplace)
    333         """
    334         if not com.is_list_like(names):
--> 335             raise TypeError("Must pass list-like as `names`.")
    336         if inplace:
    337             idx = self

TypeError: Must pass list-like as `names`.

I think the issue comes when the index of the lower dimensional DataFrame (df in this case) is already a MultiIndex. These two work:

In [45]: wp.transpose(1, 0, 2).to_frame()
Out[45]: 
              1    
            one two
major minor        
i1    A       1   2
      B       a   b
i2    A       1   2
      B       a   b

In [46]: wp.transpose(1, 2, 0).to_frame()
Out[46]: 
              1    
            one two
major minor        
A     i1      1   2
      i2      1   2
B     i1      a   b
      i2      a   b

I was expecting that wp.to_frame() would create a new MultiIndex with 3 levels:

In [63]: df = pd.DataFrame({'A': [1, 2, 1, 2], 'B': pd.to_datetime(['a', 'b', 'a', 'b'])},
                  index=pd.MultiIndex.from_tuples([('i1', 1, 'one'), ('i1', 1, 'two'), ('i2', 1, 'one'), ('i2', 1, 'two')]))

In [64]: df
Out[64]: 
          A  B
i1 1 one  1  a
     two  2  b
i2 1 one  1  a
     two  2  b

The ordering of the new MultiIndex (with wp.items inserted) is ambiguous... But something like that. You could always swaplevels later.

(side note to myself: check on if verify_integrity is validate in MultiIndex land. It doesn't get passed to _set_names).

Metadata

Metadata

Assignees

No one assigned

    Labels

    API DesignBugIndexingRelated to indexing on series/frames, not to indexes themselvesInternalsRelated to non-user accessible pandas implementationMultiIndexReshapingConcat, Merge/Join, Stack/Unstack, Explode

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions