Skip to content

Commit d403442

Browse files
author
Matias Heikkilä
committed
BUG: Fix MultiIndex DataFrame to_csv() segfault
1 parent 17247ed commit d403442

File tree

3 files changed

+15
-2
lines changed

3 files changed

+15
-2
lines changed

doc/source/whatsnew/v0.25.0.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ Indexing
336336
- Improved exception message when calling :meth:`DataFrame.iloc` with a list of non-numeric objects (:issue:`25753`).
337337
- Bug in :meth:`DataFrame.loc` and :meth:`Series.loc` where ``KeyError`` was not raised for a ``MultiIndex`` when the key was less than or equal to the number of levels in the :class:`MultiIndex` (:issue:`14885`).
338338
- Bug in which :meth:`DataFrame.append` produced an erroneous warning indicating that a ``KeyError`` will be thrown in the future when the data to be appended contains new columns (:issue:`22252`).
339-
-
339+
- Bug in which :meth:`DataFrame.to_csv` caused a segfault for a reindexed data frame, when the indices were single-level :class:`MultiIndex` (:issue:`26303`).
340340

341341

342342
Missing

pandas/core/indexes/multi.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -946,7 +946,8 @@ def _format_native_types(self, na_rep='nan', **kwargs):
946946
new_codes.append(level_codes)
947947

948948
if len(new_levels) == 1:
949-
return Index(new_levels[0])._format_native_types()
949+
# a single-level multi-index
950+
return Index(new_levels[0].take(new_codes[0]))._format_native_types()
950951
else:
951952
# reconstruct the multi-index
952953
mi = MultiIndex(levels=new_levels, codes=new_codes,

pandas/tests/frame/test_to_csv.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,6 +1220,18 @@ def test_multi_index_header(self):
12201220
expected = tm.convert_rows_list_to_csv_str(expected_rows)
12211221
assert result == expected
12221222

1223+
def test_to_csv_single_level_multi_index(self):
1224+
# see gh-26303
1225+
index = pd.Index([(1,), (2,), (3,)])
1226+
df = pd.DataFrame([[1, 2, 3]], columns=index)
1227+
with ensure_clean() as path:
1228+
df = df.reindex(columns=[(1,), (3,)])
1229+
df.to_csv(path, line_terminator='\n')
1230+
expected = b",1,3\n0,1,3\n"
1231+
1232+
with open(path, mode='rb') as f:
1233+
assert f.read() == expected
1234+
12231235
def test_gz_lineend(self):
12241236
# GH 25311
12251237
df = pd.DataFrame({'a': [1, 2]})

0 commit comments

Comments
 (0)