Skip to content

Commit adcdb5b

Browse files
committed
Merge pull request #8399 from jreback/panel
BUG: inconsisten panel indexing with aligning frame (GH7763)
2 parents cbf3679 + 6c3f184 commit adcdb5b

File tree

3 files changed

+75
-22
lines changed

3 files changed

+75
-22
lines changed

pandas/core/indexing.py

+22-14
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,13 @@ def _align_series(self, indexer, ser):
609609
def _align_frame(self, indexer, df):
610610
is_frame = self.obj.ndim == 2
611611
is_panel = self.obj.ndim >= 3
612+
612613
if isinstance(indexer, tuple):
614+
615+
aligners = [not _is_null_slice(idx) for idx in indexer]
616+
sum_aligners = sum(aligners)
617+
single_aligner = sum_aligners == 1
618+
613619
idx, cols = None, None
614620
sindexers = []
615621
for i, ix in enumerate(indexer):
@@ -626,13 +632,21 @@ def _align_frame(self, indexer, df):
626632

627633
# panel
628634
if is_panel:
629-
if len(sindexers) == 1 and idx is None and cols is None:
630-
if sindexers[0] == 0:
631-
df = df.T
632-
return self.obj.conform(df, axis=sindexers[0])
633-
df = df.T
635+
636+
# need to conform to the convention
637+
# as we are not selecting on the items axis
638+
# and we have a single indexer
639+
# GH 7763
640+
if len(sindexers) == 1 and sindexers[0] != 0:
641+
df = df.T
642+
643+
if idx is None:
644+
idx = df.index
645+
if cols is None:
646+
cols = df.columns
634647

635648
if idx is not None and cols is not None:
649+
636650
if df.index.equals(idx) and df.columns.equals(cols):
637651
val = df.copy().values
638652
else:
@@ -655,21 +669,15 @@ def _align_frame(self, indexer, df):
655669
val = df.reindex(index=ax).values
656670
return val
657671

658-
elif np.isscalar(indexer) and not is_frame:
672+
elif np.isscalar(indexer) and is_panel:
659673
idx = self.obj.axes[1]
660674
cols = self.obj.axes[2]
661675

662676
# by definition we are indexing on the 0th axis
663-
if is_panel:
664-
df = df.T
665-
666-
if idx.equals(df.index) and cols.equals(df.columns):
667-
return df.copy().values
668-
669677
# a passed in dataframe which is actually a transpose
670678
# of what is needed
671-
elif idx.equals(df.columns) and cols.equals(df.index):
672-
return df.T.copy().values
679+
if idx.equals(df.index) and cols.equals(df.columns):
680+
return df.copy().values
673681

674682
return df.reindex(idx, columns=cols).values
675683

pandas/tests/test_indexing.py

+27
Original file line numberDiff line numberDiff line change
@@ -2291,6 +2291,33 @@ def test_panel_getitem(self):
22912291
test1 = panel.ix[:, "2002"]
22922292
tm.assert_panel_equal(test1,test2)
22932293

2294+
def test_panel_setitem(self):
2295+
2296+
# GH 7763
2297+
# loc and setitem have setting differences
2298+
np.random.seed(0)
2299+
index=range(3)
2300+
columns = list('abc')
2301+
2302+
panel = Panel({'A' : DataFrame(np.random.randn(3, 3), index=index, columns=columns),
2303+
'B' : DataFrame(np.random.randn(3, 3), index=index, columns=columns),
2304+
'C' : DataFrame(np.random.randn(3, 3), index=index, columns=columns)
2305+
})
2306+
2307+
replace = DataFrame(np.eye(3,3), index=range(3), columns=columns)
2308+
expected = Panel({ 'A' : replace, 'B' : replace, 'C' : replace })
2309+
2310+
p = panel.copy()
2311+
for idx in list('ABC'):
2312+
p[idx] = replace
2313+
tm.assert_panel_equal(p, expected)
2314+
2315+
p = panel.copy()
2316+
for idx in list('ABC'):
2317+
p.loc[idx,:,:] = replace
2318+
tm.assert_panel_equal(p, expected)
2319+
2320+
22942321
def test_panel_assignment(self):
22952322

22962323
# GH3777

pandas/tests/test_panel.py

+26-8
Original file line numberDiff line numberDiff line change
@@ -668,24 +668,42 @@ def test_ix_align(self):
668668

669669
def test_ix_frame_align(self):
670670
from pandas import DataFrame
671-
df = DataFrame(np.random.randn(2, 10))
672-
df.sort_index(inplace=True)
673-
p_orig = Panel(np.random.randn(3, 10, 2))
671+
p_orig = tm.makePanel()
672+
df = p_orig.ix[0].copy()
673+
assert_frame_equal(p_orig['ItemA'],df)
674674

675675
p = p_orig.copy()
676676
p.ix[0, :, :] = df
677-
out = p.ix[0, :, :].T.reindex(df.index, columns=df.columns)
678-
assert_frame_equal(out, df)
677+
assert_panel_equal(p, p_orig)
679678

680679
p = p_orig.copy()
681680
p.ix[0] = df
682-
out = p.ix[0].T.reindex(df.index, columns=df.columns)
683-
assert_frame_equal(out, df)
681+
assert_panel_equal(p, p_orig)
682+
683+
p = p_orig.copy()
684+
p.iloc[0, :, :] = df
685+
assert_panel_equal(p, p_orig)
686+
687+
p = p_orig.copy()
688+
p.iloc[0] = df
689+
assert_panel_equal(p, p_orig)
690+
691+
p = p_orig.copy()
692+
p.loc['ItemA'] = df
693+
assert_panel_equal(p, p_orig)
694+
695+
p = p_orig.copy()
696+
p.loc['ItemA', :, :] = df
697+
assert_panel_equal(p, p_orig)
698+
699+
p = p_orig.copy()
700+
p['ItemA'] = df
701+
assert_panel_equal(p, p_orig)
684702

685703
p = p_orig.copy()
686704
p.ix[0, [0, 1, 3, 5], -2:] = df
687705
out = p.ix[0, [0, 1, 3, 5], -2:]
688-
assert_frame_equal(out, df.T.reindex([0, 1, 3, 5], p.minor_axis[-2:]))
706+
assert_frame_equal(out, df.iloc[[0,1,3,5],[2,3]])
689707

690708
# GH3830, panel assignent by values/frame
691709
for dtype in ['float64','int64']:

0 commit comments

Comments
 (0)