Skip to content

Commit c42a4c6

Browse files
committed
Merge pull request #7519 from jreback/mi2
BUG: Bug in Panel indexing with a multi-index axis (GH 7516)
2 parents 9692e0c + 28a5a05 commit c42a4c6

File tree

5 files changed

+39
-19
lines changed

5 files changed

+39
-19
lines changed

doc/source/v0.14.1.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ Experimental
166166
Bug Fixes
167167
~~~~~~~~~
168168
- Bug in ``DataFrame.where`` with a symmetric shaped frame and a passed other of a DataFrame (:issue:`7506`)
169-
169+
- Bug in Panel indexing with a multi-index axis (:issue:`7516`)
170170

171171
- Bug in timeops with non-aligned Series (:issue:`7500`)
172172

pandas/core/generic.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1632,11 +1632,11 @@ def _reindex_axes(self, axes, level, limit, method, fill_value, copy):
16321632
continue
16331633

16341634
# convert to an index if we are not a multi-selection
1635+
ax = self._get_axis(a)
16351636
if level is None:
16361637
labels = _ensure_index(labels)
16371638

16381639
axis = self._get_axis_number(a)
1639-
ax = self._get_axis(a)
16401640
new_index, indexer = ax.reindex(
16411641
labels, level=level, limit=limit, method=method)
16421642

@@ -1929,11 +1929,11 @@ def _get_bool_data(self):
19291929

19301930
def as_matrix(self, columns=None):
19311931
"""
1932-
Convert the frame to its Numpy-array representation.
1933-
1932+
Convert the frame to its Numpy-array representation.
1933+
19341934
Parameters
19351935
----------
1936-
columns: list, optional, default:None
1936+
columns: list, optional, default:None
19371937
If None, return all columns, otherwise, returns specified columns.
19381938
19391939
Returns
@@ -1942,23 +1942,23 @@ def as_matrix(self, columns=None):
19421942
If the caller is heterogeneous and contains booleans or objects,
19431943
the result will be of dtype=object. See Notes.
19441944
1945-
1945+
19461946
Notes
1947-
-----
1947+
-----
19481948
Return is NOT a Numpy-matrix, rather, a Numpy-array.
1949-
1949+
19501950
The dtype will be a lower-common-denominator dtype (implicit
19511951
upcasting); that is to say if the dtypes (even of numeric types)
19521952
are mixed, the one that accommodates all will be chosen. Use this
19531953
with care if you are not dealing with the blocks.
19541954
1955-
e.g. If the dtypes are float16 and float32, dtype will be upcast to
1956-
float32. If dtypes are int32 and uint8, dtype will be upcase to
1955+
e.g. If the dtypes are float16 and float32, dtype will be upcast to
1956+
float32. If dtypes are int32 and uint8, dtype will be upcase to
19571957
int32.
19581958
19591959
This method is provided for backwards compatibility. Generally,
19601960
it is recommended to use '.values'.
1961-
1961+
19621962
See Also
19631963
--------
19641964
pandas.DataFrame.values
@@ -1971,16 +1971,16 @@ def as_matrix(self, columns=None):
19711971
@property
19721972
def values(self):
19731973
"""Numpy representation of NDFrame
1974-
1974+
19751975
Notes
19761976
-----
19771977
The dtype will be a lower-common-denominator dtype (implicit
19781978
upcasting); that is to say if the dtypes (even of numeric types)
19791979
are mixed, the one that accommodates all will be chosen. Use this
19801980
with care if you are not dealing with the blocks.
19811981
1982-
e.g. If the dtypes are float16 and float32, dtype will be upcast to
1983-
float32. If dtypes are int32 and uint8, dtype will be upcase to
1982+
e.g. If the dtypes are float16 and float32, dtype will be upcast to
1983+
float32. If dtypes are int32 and uint8, dtype will be upcase to
19841984
int32.
19851985
"""
19861986
return self.as_matrix()

pandas/core/indexing.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,7 @@ def _getitem_nested_tuple(self, tup):
816816
# this is iterative
817817
obj = self.obj
818818
axis = 0
819-
for key in tup:
819+
for i, key in enumerate(tup):
820820

821821
if _is_null_slice(key):
822822
axis += 1
@@ -833,6 +833,13 @@ def _getitem_nested_tuple(self, tup):
833833
# has the dim of the obj changed?
834834
# GH 7199
835835
if obj.ndim < current_ndim:
836+
837+
# GH 7516
838+
# if had a 3 dim and are going to a 2d
839+
# axes are reversed on a DataFrame
840+
if i >= 1 and current_ndim == 3 and obj.ndim == 2:
841+
obj = obj.T
842+
836843
axis -= 1
837844

838845
return obj

pandas/core/panel.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -797,12 +797,15 @@ def _ixs(self, i, axis=0):
797797
axis : int
798798
"""
799799

800-
key = self._get_axis(axis)[i]
800+
ax = self._get_axis(axis)
801+
key = ax[i]
801802

802803
# xs cannot handle a non-scalar key, so just reindex here
803-
if _is_list_like(key):
804-
indexer = {self._get_axis_name(axis): key}
805-
return self.reindex(**indexer)
804+
# if we have a multi-index and a single tuple, then its a reduction (GH 7516)
805+
if not (isinstance(ax, MultiIndex) and isinstance(key, tuple)):
806+
if _is_list_like(key):
807+
indexer = {self._get_axis_name(axis): key}
808+
return self.reindex(**indexer)
806809

807810
# a reduction
808811
if axis == 0:

pandas/tests/test_indexing.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,6 +1179,16 @@ def f():
11791179
result2 = wd2.iloc[0,[0],[0,1,2]]
11801180
assert_frame_equal(result2,expected2)
11811181

1182+
# GH 7516
1183+
mi = MultiIndex.from_tuples([(0,'x'), (1,'y'), (2,'z')])
1184+
p = Panel(np.arange(3*3*3,dtype='int64').reshape(3,3,3), items=['a','b','c'], major_axis=mi, minor_axis=['u','v','w'])
1185+
result = p.iloc[:, 1, 0]
1186+
expected = Series([3,12,21],index=['a','b','c'], name='u')
1187+
assert_series_equal(result,expected)
1188+
1189+
result = p.loc[:, (1,'y'), 'u']
1190+
assert_series_equal(result,expected)
1191+
11821192
def test_iloc_getitem_doc_issue(self):
11831193

11841194
# multi axis slicing issue with single block

0 commit comments

Comments
 (0)