Skip to content

Commit 385ca3e

Browse files
committed
BUG: GH #12223, GH #15262. Allow ints for names in MultiIndex
1 parent f4edb05 commit 385ca3e

File tree

10 files changed

+41
-16
lines changed

10 files changed

+41
-16
lines changed

doc/source/whatsnew/v0.20.0.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -185,11 +185,12 @@ Other enhancements
185185
- ``Series/DataFrame.asfreq()`` have gained a ``fill_value`` parameter, to fill missing values (:issue:`3715`).
186186
- ``Series/DataFrame.resample.asfreq`` have gained a ``fill_value`` parameter, to fill missing values during resampling (:issue:`3715`).
187187
- ``pandas.tools.hashing`` has gained a ``hash_tuples`` routine, and ``hash_pandas_object`` has gained the ability to hash a ``MultiIndex`` (:issue:`15224`)
188-
- ``Series/DataFrame.squeeze()`` have gained the ``axis`` parameter. (:issue:`15339`)
188+
- ``Series/DataFrame.squeeze()`` have gained the ``axis`` parameter. (:issue:`15339`)<<<<<<< f4edb053e17e51e8c2bed7c16755c4f7f3222117
189189
- ``DataFrame.to_excel()`` has a new ``freeze_panes`` parameter to turn on Freeze Panes when exporting to Excel (:issue:`15160`)
190190
- HTML table output skips ``colspan`` or ``rowspan`` attribute if equal to 1. (:issue:`15403`)
191191
- ``pd.TimedeltaIndex`` now has a custom datetick formatter specifically designed for nanosecond level precision (:issue:`8711`)
192192
- ``pd.types.concat.union_categoricals`` gained the ``ignore_ordered`` argument to allow ignoring the ordered attribute of unioned categoricals (:issue:`13410`). See the :ref:`categorical union docs <categorical.union>` for more information.
193+
- Using numerical names in ``MultiIndex`` causes less errors. (:issue:`12223`) (:issue:`15262`)
193194

194195
.. _ISO 8601 duration: https://en.wikipedia.org/wiki/ISO_8601#Durations
195196

pandas/core/frame.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -2876,7 +2876,7 @@ def set_index(self, keys, drop=True, append=False, inplace=False,
28762876
names = [x for x in self.index.names]
28772877
if isinstance(self.index, MultiIndex):
28782878
for i in range(self.index.nlevels):
2879-
arrays.append(self.index.get_level_values(i))
2879+
arrays.append(self.index._get_level_values(i))
28802880
else:
28812881
arrays.append(self.index)
28822882

@@ -2886,9 +2886,9 @@ def set_index(self, keys, drop=True, append=False, inplace=False,
28862886
# append all but the last column so we don't have to modify
28872887
# the end of this loop
28882888
for n in range(col.nlevels - 1):
2889-
arrays.append(col.get_level_values(n))
2889+
arrays.append(col._get_level_values(n))
28902890

2891-
level = col.get_level_values(col.nlevels - 1)
2891+
level = col._get_level_values(col.nlevels - 1)
28922892
names.extend(col.names)
28932893
elif isinstance(col, Series):
28942894
level = col._values

pandas/core/groupby.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -291,8 +291,8 @@ def _set_grouper(self, obj, sort=False):
291291
# equivalent to the axis name
292292
if isinstance(ax, MultiIndex):
293293
level = ax._get_level_number(level)
294-
ax = Index(ax.get_level_values(
295-
level), name=ax.names[level])
294+
ax = Index(ax._get_level_values(level),
295+
name=ax.names[level])
296296

297297
else:
298298
if level not in (0, ax.name):
@@ -761,7 +761,7 @@ def _index_with_as_index(self, b):
761761
gp = self.grouper
762762
levels = chain((gp.levels[i][gp.labels[i][b]]
763763
for i in range(len(gp.groupings))),
764-
(original.get_level_values(i)[b]
764+
(original._get_level_values(i)[b]
765765
for i in range(original.nlevels)))
766766
new = MultiIndex.from_arrays(list(levels))
767767
new.names = gp.names + original.names

pandas/core/reshape.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -811,7 +811,8 @@ def melt(frame, id_vars=None, value_vars=None, var_name=None,
811811
mdata[value_name] = frame.values.ravel('F')
812812
for i, col in enumerate(var_name):
813813
# asanyarray will keep the columns as an Index
814-
mdata[col] = np.asanyarray(frame.columns.get_level_values(i)).repeat(N)
814+
mdata[col] = np.asanyarray(frame.columns
815+
._get_level_values(i)).repeat(N)
815816

816817
return DataFrame(mdata, columns=mcolumns)
817818

pandas/formats/format.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1566,7 +1566,7 @@ def _save_header(self):
15661566
if isinstance(index_label, list) and len(index_label) > 1:
15671567
col_line.extend([''] * (len(index_label) - 1))
15681568

1569-
col_line.extend(columns.get_level_values(i))
1569+
col_line.extend(columns._get_level_values(i))
15701570

15711571
writer.writerow(col_line)
15721572

pandas/indexes/base.py

+5
Original file line numberDiff line numberDiff line change
@@ -2352,6 +2352,11 @@ def get_level_values(self, level):
23522352
self._validate_index_level(level)
23532353
return self
23542354

2355+
def _get_level_values(self, num):
2356+
# Used to mirror implementation for MultiIndex
2357+
# GH #10461
2358+
return self.get_level_values(num)
2359+
23552360
_index_shared_docs['get_indexer'] = """
23562361
Compute indexer and mask for new index given the current index. The
23572362
indexer should be then used as an input to ndarray.take to align the

pandas/indexes/multi.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -966,7 +966,8 @@ def to_frame(self, index=True):
966966
"""
967967

968968
from pandas import DataFrame
969-
result = DataFrame({(name or level): self.get_level_values(level)
969+
result = DataFrame({(name or level):
970+
self._get_level_values(level)
970971
for name, level in
971972
zip(self.names, range(len(self.levels)))},
972973
copy=False)
@@ -1301,8 +1302,8 @@ def append(self, other):
13011302
for o in other):
13021303
arrays = []
13031304
for i in range(self.nlevels):
1304-
label = self.get_level_values(i)
1305-
appended = [o.get_level_values(i) for o in other]
1305+
label = self._get_level_values(i)
1306+
appended = [o._get_level_values(i) for o in other]
13061307
arrays.append(label.append(appended))
13071308
return MultiIndex.from_arrays(arrays, names=self.names)
13081309

pandas/io/sql.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,7 @@ def _get_column_names_and_types(self, dtype_mapper):
749749
if self.index is not None:
750750
for i, idx_label in enumerate(self.index):
751751
idx_type = dtype_mapper(
752-
self.frame.index.get_level_values(i))
752+
self.frame.index._get_level_values(i))
753753
column_names_and_types.append((text_type(idx_label),
754754
idx_type, True))
755755

pandas/tests/frame/test_combine_concat.py

+17
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,23 @@ def test_concat_axis_parameter(self):
422422
with assertRaisesRegexp(ValueError, 'No axis named'):
423423
pd.concat([series1, series2], axis='something')
424424

425+
def test_concat_numerical_names(self):
426+
# #15262 # #12223
427+
df = pd.DataFrame({'col': range(9)},
428+
index=(pd.MultiIndex
429+
.from_product([['A0', 'A1', 'A2'],
430+
['B0', 'B1', 'B2']],
431+
names=[1, 2])))
432+
result = pd.concat((df.iloc[:2, :], df.iloc[-2:, :]))
433+
expected = pd.DataFrame({'col': [0, 1, 7, 8]},
434+
dtype='int32',
435+
index=pd.MultiIndex.from_tuples([('A0', 'B0'),
436+
('A0', 'B1'),
437+
('A2', 'B1'),
438+
('A2', 'B2')],
439+
names=[1, 2]))
440+
tm.assert_frame_equal(result, expected)
441+
425442

426443
class TestDataFrameCombineFirst(tm.TestCase, TestData):
427444

pandas/util/doctools.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,12 @@ def _insert_index(self, data):
113113
else:
114114
for i in range(idx_nlevels):
115115
data.insert(i, 'Index{0}'.format(i),
116-
data.index.get_level_values(i))
116+
data.index._get_level_values(i))
117117

118118
col_nlevels = data.columns.nlevels
119119
if col_nlevels > 1:
120-
col = data.columns.get_level_values(0)
121-
values = [data.columns.get_level_values(i).values
120+
col = data.columns._get_level_values(0)
121+
values = [data.columns._get_level_values(i).values
122122
for i in range(1, col_nlevels)]
123123
col_df = pd.DataFrame(values)
124124
data.columns = col_df.columns

0 commit comments

Comments
 (0)