diff --git a/pandas/core/internals/construction.py b/pandas/core/internals/construction.py index 57ed2555761be..927baf59a4a6a 100644 --- a/pandas/core/internals/construction.py +++ b/pandas/core/internals/construction.py @@ -576,11 +576,16 @@ def _convert_object_array(content, columns, coerce_float=False, dtype=None): else: if len(columns) != len(content): # pragma: no cover # caller's responsibility to check for this... - raise AssertionError( - f"{len(columns)} columns passed, passed data had " - f"{len(content)} columns" - ) - + # Its possible that the user may be trying to pass a MultiIndex here. + # Attempt to convert columns to MultiIndex, and check length again. + # This conversion should be safe to do, as the input expects an Index + # and the colums are left unmodified throughout the rest of this function. + columns = ensure_index(columns) + if len(columns) != len(content): + raise AssertionError( + f"{len(columns)} columns passed, passed data had " + f"{len(content)} columns" + ) # provide soft conversion of object dtypes def convert(arr): if dtype != object and dtype != np.object: diff --git a/pandas/tests/indexes/multi/test_nested_list_data.py b/pandas/tests/indexes/multi/test_nested_list_data.py new file mode 100644 index 0000000000000..d41dc0067ab53 --- /dev/null +++ b/pandas/tests/indexes/multi/test_nested_list_data.py @@ -0,0 +1,42 @@ +import pandas as pd +import pandas._testing as tm +import numpy as np +import pytest + + +''' +This code is meant to test the fix implemented for issue #14467. +https://github.com/pandas-dev/pandas/issues/14467 +''' + +class TestNestedListDataMultiIndex: + + def test_nested_list(self): + # Case from issue, creating data from np.array works, and should match this case + result = pd.DataFrame([[1, 2, 3], [4, 5, 6]], + index=[['gibberish']*2, [0, 1]], + columns=[['baldersash']*3, [10, 20, 30]]) + + expected = pd.DataFrame(np.array([[1, 2, 3], [4, 5, 6]]), + index=[['gibberish']*2, [0, 1]], + columns=[['baldersash']*3, [10, 20, 30]]) + tm.assert_index_equal(result.columns, expected.columns) + + def test_nest_list_with_multiIndex(self): + # Creating from a multiIndex should also still work + m = pd.MultiIndex.from_arrays([['baldersash']*3, [10, 20, 30]]) + result = pd.DataFrame([[1, 2, 3], [4, 5, 6]], + index=[['gibberish']*2, [0, 1]], + columns=m) + + expected = pd.DataFrame(np.array([[1, 2, 3], [4, 5, 6]]), + index=[['gibberish']*2, [0, 1]], + columns=[['baldersash']*3, [10, 20, 30]]) + tm.assert_index_equal(result.columns, expected.columns) + + def test_wrong_length_raises_error(self): + # Make sure the code raises an error if the nested lists have the wrong length + with pytest.raises(ValueError): + result = pd.DataFrame([[1, 2, 3], [4, 5, 6]], + index=[['gibberish']*2, [0, 1]], + columns=[['baldersash']*2, [10, 20]]) \ No newline at end of file