Skip to content

Commit 9b37ff9

Browse files
committed
BUG GH11733
1 parent 32df1e6 commit 9b37ff9

File tree

4 files changed

+66
-17
lines changed

4 files changed

+66
-17
lines changed

doc/source/io.rst

+7-5
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,13 @@ names : array-like, default ``None``
123123
List of column names to use. If file contains no header row, then you should
124124
explicitly pass ``header=None``. Duplicates in this list are not allowed unless
125125
``mangle_dupe_cols=True``, which is the default.
126-
index_col : int or sequence or ``False``, default ``None``
127-
Column to use as the row labels of the DataFrame. If a sequence is given, a
128-
MultiIndex is used. If you have a malformed file with delimiters at the end of
129-
each line, you might consider ``index_col=False`` to force pandas to *not* use
130-
the first column as the index (row names).
126+
index_col : int or sequence or ``False``, default ``None``
127+
Column (0-indexed) to use as the row labels of the DataFrame. If a
128+
sequence is given, those columns will be combined into a ``MultiIndex``.
129+
If ``None`` (default), pandas will use the first column as the
130+
index. If ``False``, force pandas to *not* use the first column as the index
131+
(row names). ``None`` should be considered if you have a malformed file with
132+
delimiters at the end of each line.
131133
usecols : array-like or callable, default ``None``
132134
Return a subset of the columns. If array-like, all elements must either
133135
be positional (i.e. integer indices into the document columns) or strings

pandas/io/excel.py

+17-7
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,12 @@
7575
Rows to skip at the beginning (0-indexed)
7676
skip_footer : int, default 0
7777
Rows at the end to skip (0-indexed)
78-
index_col : int, list of ints, default None
79-
Column (0-indexed) to use as the row labels of the DataFrame.
80-
Pass None if there is no such column. If a list is passed,
81-
those columns will be combined into a ``MultiIndex``
78+
index_col : int or sequence or ``False``, default ``None``
79+
Column (0-indexed) to use as the row labels of the DataFrame. If a
80+
sequence is given, those columns will be combined into a ``MultiIndex``.
81+
If ``None`` (default), pandas will use the first column as the
82+
index. If ``False``, force pandas to *not* use the first column as the
83+
index (row names).
8284
names : array-like, default None
8385
List of column names to use. If file contains no header row,
8486
then you should explicitly pass header=None
@@ -351,6 +353,11 @@ def _parse_excel(self, sheetname=0, header=0, skiprows=None, names=None,
351353
raise NotImplementedError("date_parser keyword of read_excel "
352354
"is not implemented")
353355

356+
# At the API, index_col is False means there is no index column
357+
have_index_col = (index_col is not False)
358+
if index_col is False:
359+
index_col = None
360+
354361
import xlrd
355362
from xlrd import (xldate, XL_CELL_DATE,
356363
XL_CELL_ERROR, XL_CELL_BOOLEAN,
@@ -472,10 +479,13 @@ def _parse_cell(cell_contents, cell_typ):
472479

473480
data[row], control_row = _fill_mi_header(
474481
data[row], control_row)
475-
header_name, data[row] = _pop_header_name(
476-
data[row], index_col)
482+
if have_index_col:
483+
header_name, data[row] = _pop_header_name(
484+
data[row], index_col)
485+
else:
486+
header_name = ''
477487
header_names.append(header_name)
478-
else:
488+
elif have_index_col:
479489
data[header] = _trim_excel_header(data[header])
480490

481491
if is_list_like(index_col):

pandas/io/parsers.py

+6-5
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,12 @@
8484
List of column names to use. If file contains no header row, then you
8585
should explicitly pass header=None. Duplicates in this list are not
8686
allowed unless mangle_dupe_cols=True, which is the default.
87-
index_col : int or sequence or False, default None
88-
Column to use as the row labels of the DataFrame. If a sequence is given, a
89-
MultiIndex is used. If you have a malformed file with delimiters at the end
90-
of each line, you might consider index_col=False to force pandas to _not_
91-
use the first column as the index (row names)
87+
index_col : int or sequence or ``False``, default ``None``
88+
Column (0-indexed) to use as the row labels of the DataFrame. If a
89+
sequence is given, those columns will be combined into a ``MultiIndex``.
90+
If ``None`` (default), pandas will use the first column as the
91+
index. If ``False``, force pandas to *not* use the first column as the
92+
index (row names).
9293
usecols : array-like or callable, default None
9394
Return a subset of the columns. If array-like, all elements must either
9495
be positional (i.e. integer indices into the document columns) or strings

pandas/tests/io/test_excel.py

+36
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,42 @@ def test_read_excel_multiindex(self):
777777
header=[0, 1], skiprows=2)
778778
tm.assert_frame_equal(actual, expected)
779779

780+
def test_read_excel_multiindex_colindex_false(self):
781+
# GH 11733
782+
mi = MultiIndex(levels=[['Unnamed: 0_level_0', u'bar', u'foo'],
783+
['Unnamed: 0_level_1', u'a', u'b']],
784+
labels=[[0, 2, 2, 1, 1], [0, 1, 2, 1, 2]],
785+
names=[u'', u''])
786+
mi_file = os.path.join(self.dirpath, 'testmultiindex' + self.ext)
787+
788+
expected = DataFrame([[0, 1, 2.5, pd.Timestamp('2015-01-01'), True],
789+
[1, 2, 3.5, pd.Timestamp('2015-01-02'), False],
790+
[2, 3, 4.5, pd.Timestamp('2015-01-03'), False],
791+
[3, 4, 5.5, pd.Timestamp('2015-01-04'), True]],
792+
columns=mi)
793+
794+
actual = read_excel(mi_file, 'mi_column',
795+
header=[0, 1], index_col=False)
796+
tm.assert_frame_equal(actual, expected)
797+
798+
mi = MultiIndex(levels=[[u'c1', u'bar', u'foo'],
799+
[u'c2', u'a', u'b']],
800+
labels=[[0, 2, 2, 1, 1], [0, 1, 2, 1, 2]],
801+
names=[u'', u''])
802+
expected.columns = mi
803+
actual = read_excel(mi_file, 'mi_column_name',
804+
header=[0, 1], index_col=False)
805+
tm.assert_frame_equal(actual, expected)
806+
807+
mi = MultiIndex(levels=[[u'c1', u'bar', u'foo'],
808+
[u'c2', 1, 2]],
809+
labels=[[0, 2, 2, 1, 1], [0, 1, 2, 1, 2]],
810+
names=[u'', u''])
811+
expected.columns = mi
812+
actual = read_excel(mi_file, 'name_with_int',
813+
index_col=False, header=[0, 1])
814+
tm.assert_frame_equal(actual, expected)
815+
780816
def test_read_excel_multiindex_empty_level(self):
781817
# GH 12453
782818
_skip_if_no_xlsxwriter()

0 commit comments

Comments
 (0)