Repository: pandas-dev/pandas

Issue:
ER: multiindexes in no-data DataFrame constructor should yield a nan frame
as it stands

```
In [24]: tuples = [(randint(10), randint(10)) for _ in range(10)]

In [25]: mi = MultiIndex.from_tuples(tuples)

In [26]: df = DataFrame(index=mi, columns=mi)
```

fails, whereas single level indexes work fine

```
In [27]: df = DataFrame(index=range(10), columns=range(10))

In [28]: df
Out[28]:
     0    1    2    3    4    5    6    7    8    9
0  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
1  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
2  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
3  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
4  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
5  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
6  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
7  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
8  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
9  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
```



Discussion:
Or at least a non-crazy error:

``` python
---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)
<ipython-input-11-243e9e4b4a0c> in <module>()
----> 1 df = DataFrame(index=mi, columns=mi)

../pandas/pandas/core/frame.py in __init__(self, data, index, columns, dtype, copy)
    395             mgr = self._init_mgr(data, index, columns, dtype=dtype, copy=copy)
    396         elif isinstance(data, dict):
--> 397             mgr = self._init_dict(data, index, columns, dtype=dtype)
    398         elif isinstance(data, ma.MaskedArray):
    399             mask = ma.getmaskarray(data)

../pandas/pandas/core/frame.py in _init_dict(self, data, index, columns, dtype)
    526
    527         return _arrays_to_mgr(arrays, data_names, index, columns,
--> 528                               dtype=dtype)
    529
    530     def _init_ndarray(self, values, index, columns, dtype=None,

../python/pandas/pandas/core/frame.py in _arrays_to_mgr(arrays, arr_names, index, columns, dtype)
   5703     axes = [_ensure_index(columns), _ensure_index(index)]
   5704
-> 5705     return create_block_manager_from_arrays(arrays, arr_names, axes)
   5706
   5707 def extract_index(data):

../pandas/pandas/core/internals.pyc in create_block_manager_from_arrays(arrays, names, axes)
   2232 def create_block_manager_from_arrays(arrays, names, axes):
   2233     try:
-> 2234         blocks = form_blocks(arrays, names, axes)
   2235         mgr = BlockManager(blocks, axes)
   2236         mgr._consolidate_inplace()

../pandas/pandas/core/internals.pyc in form_blocks(arrays, names, axes)
   2315
   2316     if len(object_items) > 0:
-> 2317         object_blocks = _simple_blockify(object_items, items, np.object_, is_unique=is_unique)
   2318         blocks.extend(object_blocks)
   2319

../pandas/pandas/core/internals.pyc in _simple_blockify(tuples, ref_items, dtype, is_unique)
   2334 def _simple_blockify(tuples, ref_items, dtype, is_unique=True):
   2335     """ return a single array of a block that has a single dtype; if dtype is not None, coerce to this dtype """
-> 2336     block_items, values, placement = _stack_arrays(tuples, ref_items, dtype)
   2337
   2338     # CHECK DTYPE?

../pandas/pandas/core/internals.pyc in _stack_arrays(tuples, ref_items, dtype)
   2395         items = _ensure_index([ n for n in names if n in ref_items ])
   2396         if len(items) != len(stacked):
-> 2397             raise Exception("invalid names passed _stack_arrays")
   2398
   2399     return items, stacked, placement

Exception: invalid names passed _stack_arrays
```

you don't like the error msg? (I am not sure i even remember what it's for!)

@jreback :P

On Fri, Jun 28, 2013 at 7:07 PM, jreback notifications@github.com wrote:

> you don't like the error msg? (I am not sure i even remember what it's
> for!)
> 
> —
> Reply to this email directly or view it on GitHubhttps://github.com/pydata/pandas/issues/4078#issuecomment-20219320
> .

just got to the bottom of this: it only happens for a duplicate index value. works fine when there are no duplicates

does this fail for you on curent master?


Resolving patch:
diff --git a/pandas/core/internals.py b/pandas/core/internals.py
--- a/pandas/core/internals.py
+++ b/pandas/core/internals.py
@@ -3530,9 +3530,16 @@ def _shape_compat(x):
     if ref_items.is_unique:
         items = ref_items[ref_items.isin(names)]
     else:
-        items = _ensure_index([n for n in names if n in ref_items])
-        if len(items) != len(stacked):
-            raise Exception("invalid names passed _stack_arrays")
+        # a mi
+        if isinstance(ref_items, MultiIndex):
+            names = MultiIndex.from_tuples(names)
+            items = ref_items[ref_items.isin(names)]
+
+        # plain old dups
+        else:
+            items = _ensure_index([n for n in names if n in ref_items])
+            if len(items) != len(stacked):
+                raise ValueError("invalid names passed _stack_arrays")
 
     return items, stacked, placement
 


Test patch:
diff --git a/pandas/tests/test_frame.py b/pandas/tests/test_frame.py
--- a/pandas/tests/test_frame.py
+++ b/pandas/tests/test_frame.py
@@ -2263,10 +2263,6 @@ def test_constructor_overflow_int64(self):
         df_crawls = DataFrame(data)
         self.assert_(df_crawls['uid'].dtype == object)
 
-    def test_is_mixed_type(self):
-        self.assert_(not self.frame._is_mixed_type)
-        self.assert_(self.mixed_frame._is_mixed_type)
-
     def test_constructor_ordereddict(self):
         import random
         nitems = 100
@@ -2319,6 +2315,19 @@ def test_constructor_dict(self):
         frame = DataFrame({'A': [], 'B': []}, columns=['A', 'B'])
         self.assert_(frame.index.equals(Index([])))
 
+    def test_constructor_multi_index(self):
+        # GH 4078
+        # construction error with mi and all-nan frame
+        tuples = [(2, 3), (3, 3), (3, 3)]
+        mi = MultiIndex.from_tuples(tuples)
+        df = DataFrame(index=mi,columns=mi)
+        self.assert_(pd.isnull(df).values.ravel().all())
+
+        tuples = [(3, 3), (2, 3), (3, 3)]
+        mi = MultiIndex.from_tuples(tuples)
+        df = DataFrame(index=mi,columns=mi)
+        self.assert_(pd.isnull(df).values.ravel().all())
+
     def test_constructor_error_msgs(self):
         msg = "Mixing dicts with non-Series may lead to ambiguous ordering."
         # mix dict and array, wrong size
@@ -9489,6 +9498,10 @@ def test_get_X_columns(self):
         self.assert_(np.array_equal(df._get_numeric_data().columns,
                                     ['a', 'b', 'e']))
 
+    def test_is_mixed_type(self):
+        self.assert_(not self.frame._is_mixed_type)
+        self.assert_(self.mixed_frame._is_mixed_type)
+
     def test_get_numeric_data(self):
         intname = np.dtype(np.int_).name
         floatname = np.dtype(np.float_).name