Skip to content

Commit 6eb705f

Browse files
Ben Kandeljreback
Ben Kandel
authored andcommitted
BUG: Indexing MultiIndex with Series failed.
Previously, accessing elements of a MultiIndex-indexed DataFrame with a Series failed. This changes that behavior so that it is possible to use a Series to access elements from a MultiIndex-indexed DataFrame, just as one would use a list. closes #14730 Author: Ben Kandel <[email protected]> Closes #15041 from bkandel/gh-14730-multiindex-series and squashes the following commits: 3698087 [Ben Kandel] appveyor 51b8ccf [Ben Kandel] appveyor 6c03932 [Ben Kandel] Address comments. bfba946 [Ben Kandel] BUG: Indexing MultiIndex with Series failed.
1 parent b957f6f commit 6eb705f

File tree

4 files changed

+41
-13
lines changed

4 files changed

+41
-13
lines changed

doc/source/whatsnew/v0.20.0.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ Bug Fixes
299299
- Bug in ``pd.to_numeric()`` in which float and unsigned integer elements were being improperly casted (:issue:`14941`, :issue:`15005`)
300300
- Bug in ``pd.read_csv()`` in which the ``dialect`` parameter was not being verified before processing (:issue:`14898`)
301301

302-
302+
- Bug in ``DataFrame.loc`` with indexing a ``MultiIndex`` with a ``Series`` indexer (:issue:`14730`)
303303

304304
- Bug in ``pd.read_msgpack()`` in which ``Series`` categoricals were being improperly processed (:issue:`14901`)
305305
- Bug in ``Series.ffill()`` with mixed dtypes containing tz-aware datetimes. (:issue:`14956`)

pandas/core/indexing.py

+3
Original file line numberDiff line numberDiff line change
@@ -1461,6 +1461,9 @@ def _getitem_axis(self, key, axis=0):
14611461
if isinstance(labels, MultiIndex):
14621462
if (not isinstance(key, tuple) and len(key) > 1 and
14631463
not isinstance(key[0], tuple)):
1464+
if isinstance(key, ABCSeries):
1465+
# GH 14730
1466+
key = list(key)
14641467
key = tuple([key])
14651468

14661469
# an iterable multi-selection

pandas/tests/indexes/test_multi.py

+15-12
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,29 @@
11
# -*- coding: utf-8 -*-
22

3-
from datetime import timedelta
4-
from itertools import product
5-
import nose
63
import re
74
import warnings
85

9-
from pandas import (DataFrame, date_range, period_range, MultiIndex, Index,
10-
CategoricalIndex, compat)
11-
from pandas.core.common import PerformanceWarning, UnsortedIndexError
12-
from pandas.indexes.base import InvalidIndexError
13-
from pandas.compat import range, lrange, u, PY3, long, lzip
6+
from datetime import timedelta
7+
from itertools import product
8+
9+
import nose
1410

1511
import numpy as np
1612

17-
from pandas.util.testing import (assert_almost_equal, assertRaises,
18-
assertRaisesRegexp, assert_copy)
13+
import pandas as pd
14+
15+
from pandas import (CategoricalIndex, DataFrame, Index, MultiIndex,
16+
compat, date_range, period_range)
17+
from pandas.compat import PY3, long, lrange, lzip, range, u
18+
from pandas.core.common import PerformanceWarning, UnsortedIndexError
19+
from pandas.indexes.base import InvalidIndexError
20+
from pandas.lib import Timestamp
1921

2022
import pandas.util.testing as tm
2123

22-
import pandas as pd
23-
from pandas.lib import Timestamp
24+
from pandas.util.testing import (assertRaises, assertRaisesRegexp,
25+
assert_almost_equal, assert_copy)
26+
2427

2528
from .common import Base
2629

pandas/tests/indexing/test_indexing.py

+22
Original file line numberDiff line numberDiff line change
@@ -1210,6 +1210,28 @@ def test_loc_getitem_label_array_like(self):
12101210
self.check_result('array like', 'loc', Series(index=[4, 8, 12]).index,
12111211
'ix', [4, 8, 12], typs=['ints'], axes=2)
12121212

1213+
def test_loc_getitem_series(self):
1214+
# GH14730
1215+
# passing a series as a key with a MultiIndex
1216+
index = MultiIndex.from_product([[1, 2, 3], ['A', 'B', 'C']])
1217+
x = Series(index=index, data=range(9), dtype=np.float64)
1218+
y = Series([1, 3])
1219+
expected = Series(
1220+
data=[0, 1, 2, 6, 7, 8],
1221+
index=MultiIndex.from_product([[1, 3], ['A', 'B', 'C']]),
1222+
dtype=np.float64)
1223+
result = x.loc[y]
1224+
tm.assert_series_equal(result, expected)
1225+
1226+
result = x.loc[[1, 3]]
1227+
tm.assert_series_equal(result, expected)
1228+
1229+
empty = Series(data=[], dtype=np.float64)
1230+
expected = Series([], index=MultiIndex(
1231+
levels=index.levels, labels=[[], []], dtype=np.float64))
1232+
result = x.loc[empty]
1233+
tm.assert_series_equal(result, expected)
1234+
12131235
def test_loc_getitem_bool(self):
12141236
# boolean indexers
12151237
b = [True, False, True, False]

0 commit comments

Comments
 (0)