@@ -5120,7 +5120,6 @@ def test_to_and_from_dataframe(self) -> None:
51205120 # from_dataframe attempts to broadcast across because it doesn't know better, so cat must be converted
51215121 ds ["cat" ] = (("x" , "y" ), np .stack ((ds ["cat" ].to_numpy (), ds ["cat" ].to_numpy ())))
51225122 assert_identical (ds .assign_coords (x = [0 , 1 ]), Dataset .from_dataframe (actual ))
5123-
51245123 # Check multiindex reordering
51255124 new_order = ["x" , "y" ]
51265125 # revert broadcasting fix above for 1d arrays
@@ -5154,6 +5153,41 @@ def test_to_and_from_dataframe(self) -> None:
51545153 ):
51555154 ds .to_dataframe (dim_order = invalid_order )
51565155
5156+ # test a case with a MultiIndex along a single dimension
5157+ data_dict = dict (
5158+ x = [1 , 2 , 1 , 2 , 1 ], y = ["a" , "a" , "b" , "b" , "b" ], z = [5 , 10 , 15 , 20 , 25 ]
5159+ )
5160+ data_dict_w_dims = {k : ("single_dim" , v ) for k , v in data_dict .items ()}
5161+
5162+ # Dataset multi-indexed along "single_dim" by "x" and "y"
5163+ ds = Dataset (data_dict_w_dims ).set_coords (["x" , "y" ]).set_xindex (["x" , "y" ])
5164+ expected = pd .DataFrame (data_dict ).set_index (["x" , "y" ])
5165+ actual = ds .to_dataframe ()
5166+ assert expected .equals (actual )
5167+ # should be possible to reset index, as there should be no duplication
5168+ # between index and columns, and dataframes should still be equal
5169+ assert expected .reset_index ().equals (actual .reset_index ())
5170+
5171+ # MultiIndex deduplication should not affect other coordinates.
5172+ mindex_single = pd .MultiIndex .from_product (
5173+ [list (range (6 )), list ("ab" )], names = ["A" , "B" ]
5174+ )
5175+ ds = DataArray (
5176+ range (12 ), [("MI" , mindex_single )], dims = "MI" , name = "test"
5177+ )._to_dataset_whole ()
5178+ ds .coords ["C" ] = "a single value"
5179+ ds .coords ["D" ] = ds .coords ["A" ] ** 2
5180+ expected = pd .DataFrame (
5181+ dict (
5182+ test = range (12 ),
5183+ C = "a single value" ,
5184+ D = [0 , 0 , 1 , 1 , 4 , 4 , 9 , 9 , 16 , 16 , 25 , 25 ],
5185+ )
5186+ ).set_index (mindex_single )
5187+ actual = ds .to_dataframe ()
5188+ assert expected .equals (actual )
5189+ assert expected .reset_index ().equals (actual .reset_index ())
5190+
51575191 # check pathological cases
51585192 df = pd .DataFrame ([1 ])
51595193 actual_ds = Dataset .from_dataframe (df )
0 commit comments