Skip to content

Commit 453d40a

Browse files
committed
deprecate and test has_index_names
1 parent 11fbb7f commit 453d40a

File tree

3 files changed

+53
-25
lines changed

3 files changed

+53
-25
lines changed

pandas/core/format.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1833,25 +1833,21 @@ def _format_hierarchical_rows(self):
18331833
(list, tuple, np.ndarray, Index)):
18341834
index_labels = self.index_label
18351835

1836+
# MultiIndex columns require an extra row
1837+
# with index names (blank if None) for
1838+
# unambigous round-trip
18361839
if isinstance(self.columns, MultiIndex):
18371840
self.rowcounter += 1
18381841

18391842
# if index labels are not empty go ahead and dump
18401843
if (any(x is not None for x in index_labels)
18411844
and self.header is not False):
18421845

1843-
# if not self.merge_cells or not isinstance(self.columns, MultiIndex):
1844-
# self.rowcounter -= 1
1845-
18461846
for cidx, name in enumerate(index_labels):
18471847
yield ExcelCell(self.rowcounter - 1,
18481848
cidx,
18491849
name,
18501850
header_style)
1851-
# elif isinstance(self.columns, MultiIndex):
1852-
# # if multiIndex columns, leave a blank row
1853-
# # regardless of labels
1854-
# self.rowcounter += 1
18551851

18561852
if self.merge_cells:
18571853
# Format hierarchical rows as merged cells.

pandas/io/excel.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,9 @@ def read_excel(io, sheetname=0, **kwds):
135135
data will be read in as floats: Excel stores all numbers as floats
136136
internally
137137
has_index_names : boolean, default False
138-
True if the cols defined in index_col have an index name and are
139-
not in the header. Index name will be placed on a separate line below
140-
the header.
138+
DEPCRECATED: for version 0.17+ index names will be automatically inferred
139+
based on index_col. To read Excel output from 0.16.2 and prior that
140+
had saved index names, use True.
141141
142142
Returns
143143
-------
@@ -227,7 +227,6 @@ def parse(self, sheetname=0, header=0, skiprows=None, skip_footer=0,
227227
Row to use for the column labels of the parsed DataFrame
228228
If a list of integers is passed those row positions will
229229
be combined into a ``MultiIndex``
230-
Row to use for the column labels of the parsed DataFrame
231230
skiprows : list-like
232231
Rows to skip at the beginning (0-indexed)
233232
skip_footer : int, default 0
@@ -261,8 +260,9 @@ def parse(self, sheetname=0, header=0, skiprows=None, skip_footer=0,
261260
numeric data will be read in as floats: Excel stores all numbers as
262261
floats internally.
263262
has_index_names : boolean, default False
264-
True if the cols defined in index_col have an index name and are
265-
not in the header
263+
DEPCRECATED: for version 0.17+ index names will be automatically inferred
264+
based on index_col. To read Excel output from 0.16.2 and prior that
265+
had saved index names, use True.
266266
verbose : boolean, default False
267267
Set to True to print a single statement when reading each
268268
excel sheet.
@@ -277,9 +277,11 @@ def parse(self, sheetname=0, header=0, skiprows=None, skip_footer=0,
277277
if skipfooter is not None:
278278
skip_footer = skipfooter
279279

280-
# if has_index_names:
281-
# warning.warn("The has_index_names argument is deprecated; index names"
282-
# "will be automatically inferred based on index_col.")
280+
if has_index_names:
281+
warn("\nThe has_index_names argument is deprecated; index names "
282+
"will be automatically inferred based on index_col.\n"
283+
"This argmument is still necessary if reading Excel output "
284+
"from 0.16.2 or prior with index names.", FutureWarning)
283285

284286
return self._parse_excel(sheetname=sheetname, header=header,
285287
skiprows=skiprows,

pandas/io/tests/test_excel.py

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,42 @@ def test_excel_multindex_roundtrip(self):
601601
header=list(range(c_idx_levels)))
602602
tm.assert_frame_equal(df, act, check_names=check_names)
603603

604+
def test_excel_oldindex_format(self):
605+
#GH 4679
606+
_skip_if_no_xlrd()
607+
data = np.array([['R0C0', 'R0C1', 'R0C2', 'R0C3', 'R0C4'],
608+
['R1C0', 'R1C1', 'R1C2', 'R1C3', 'R1C4'],
609+
['R2C0', 'R2C1', 'R2C2', 'R2C3', 'R2C4'],
610+
['R3C0', 'R3C1', 'R3C2', 'R3C3', 'R3C4'],
611+
['R4C0', 'R4C1', 'R4C2', 'R4C3', 'R4C4']])
612+
columns = ['C_l0_g0', 'C_l0_g1', 'C_l0_g2', 'C_l0_g3', 'C_l0_g4']
613+
mi = MultiIndex(levels=[['R_l0_g0', 'R_l0_g1', 'R_l0_g2', 'R_l0_g3', 'R_l0_g4'],
614+
['R_l1_g0', 'R_l1_g1', 'R_l1_g2', 'R_l1_g3', 'R_l1_g4']],
615+
labels=[[0, 1, 2, 3, 4], [0, 1, 2, 3, 4]],
616+
names=['R0', 'R1'])
617+
si = Index(['R_l0_g0', 'R_l0_g1', 'R_l0_g2', 'R_l0_g3', 'R_l0_g4'], name='R0')
618+
619+
in_file = os.path.join(self.dirpath, 'test_index_name_pre17.xlsx')
620+
621+
expected = pd.DataFrame(data, index=si, columns=columns)
622+
with tm.assert_produces_warning(FutureWarning):
623+
actual = pd.read_excel(in_file, 'single_names', has_index_names=True)
624+
tm.assert_frame_equal(actual, expected)
625+
626+
expected.index.name = None
627+
actual = pd.read_excel(in_file, 'single_no_names')
628+
tm.assert_frame_equal(actual, expected)
629+
630+
expected.index = mi
631+
with tm.assert_produces_warning(FutureWarning):
632+
actual = pd.read_excel(in_file, 'multi_names', has_index_names=True)
633+
tm.assert_frame_equal(actual, expected)
634+
635+
expected.index.names = [None, None]
636+
actual = pd.read_excel(in_file, 'multi_no_names', index_col=[0,1])
637+
tm.assert_frame_equal(actual, expected, check_names=False)
638+
639+
604640

605641
class XlsReaderTests(XlrdTests, tm.TestCase):
606642
ext = '.xls'
@@ -866,7 +902,6 @@ def test_roundtrip_indexlabels(self):
866902
reader = ExcelFile(path)
867903
recons = reader.parse('test1',
868904
index_col=0,
869-
has_index_names=self.merge_cells
870905
).astype(np.int64)
871906
frame.index.names = ['test']
872907
self.assertEqual(frame.index.names, recons.index.names)
@@ -879,7 +914,6 @@ def test_roundtrip_indexlabels(self):
879914
reader = ExcelFile(path)
880915
recons = reader.parse('test1',
881916
index_col=0,
882-
has_index_names=self.merge_cells
883917
).astype(np.int64)
884918
frame.index.names = ['test']
885919
self.assertEqual(frame.index.names, recons.index.names)
@@ -892,7 +926,6 @@ def test_roundtrip_indexlabels(self):
892926
reader = ExcelFile(path)
893927
recons = reader.parse('test1',
894928
index_col=0,
895-
has_index_names=self.merge_cells
896929
).astype(np.int64)
897930
frame.index.names = ['test']
898931
tm.assert_frame_equal(frame, recons.astype(bool))
@@ -922,8 +955,7 @@ def test_excel_roundtrip_indexname(self):
922955

923956
xf = ExcelFile(path)
924957
result = xf.parse(xf.sheet_names[0],
925-
index_col=0,
926-
has_index_names=self.merge_cells)
958+
index_col=0)
927959

928960
tm.assert_frame_equal(result, df)
929961
self.assertEqual(result.index.name, 'foo')
@@ -1010,8 +1042,7 @@ def test_to_excel_multiindex(self):
10101042
frame.to_excel(path, 'test1', merge_cells=self.merge_cells)
10111043
reader = ExcelFile(path)
10121044
df = reader.parse('test1', index_col=[0, 1],
1013-
parse_dates=False,
1014-
has_index_names=self.merge_cells)
1045+
parse_dates=False)
10151046
tm.assert_frame_equal(frame, df)
10161047
self.assertEqual(frame.index.names, df.index.names)
10171048

@@ -1028,8 +1059,7 @@ def test_to_excel_multiindex_dates(self):
10281059
tsframe.to_excel(path, 'test1', merge_cells=self.merge_cells)
10291060
reader = ExcelFile(path)
10301061
recons = reader.parse('test1',
1031-
index_col=[0, 1],
1032-
has_index_names=self.merge_cells)
1062+
index_col=[0, 1])
10331063

10341064
tm.assert_frame_equal(tsframe, recons)
10351065
self.assertEqual(recons.index.names, ('time', 'foo'))

0 commit comments

Comments
 (0)