Skip to content

Commit 0f72731

Browse files
committed
BUG: (GH3830), panel assignment using loc with a transpose frame did not work
1 parent e8a528d commit 0f72731

File tree

3 files changed

+49
-4
lines changed

3 files changed

+49
-4
lines changed

doc/source/release.rst

+1
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ pandas 0.13
131131
(:issue:`4170`, :issue:`4440`)
132132
- Fixed Panel slicing issued in ``xs`` that was returning an incorrect dimmed object
133133
(:issue:`4016`)
134+
- Fixed Panel assignment with a transposed frame (:issue:`3830`)
134135

135136
pandas 0.12
136137
===========

pandas/core/indexing.py

+23-4
Original file line numberDiff line numberDiff line change
@@ -208,12 +208,11 @@ def _align_series(self, indexer, ser):
208208
raise ValueError('Incompatible indexer with Series')
209209

210210
def _align_frame(self, indexer, df):
211-
from pandas import DataFrame
212-
is_frame = isinstance(self.obj, DataFrame)
213-
if not is_frame:
214-
df = df.T
211+
is_frame = self.obj.ndim == 2
212+
is_panel = self.obj.ndim >= 3
215213
if isinstance(indexer, tuple):
216214
idx, cols = None, None
215+
sindexers = []
217216
for i, ix in enumerate(indexer):
218217
ax = self.obj.axes[i]
219218
if com._is_sequence(ix) or isinstance(ix, slice):
@@ -223,6 +222,16 @@ def _align_frame(self, indexer, df):
223222
cols = ax[ix].ravel()
224223
else:
225224
break
225+
else:
226+
sindexers.append(i)
227+
228+
# panel
229+
if is_panel:
230+
if len(sindexers) == 1 and idx is None and cols is None:
231+
if sindexers[0] == 0:
232+
df = df.T
233+
return self.obj.conform(df,axis=sindexers[0])
234+
df = df.T
226235

227236
if idx is not None and cols is not None:
228237
if df.index.equals(idx) and df.columns.equals(cols):
@@ -244,8 +253,18 @@ def _align_frame(self, indexer, df):
244253
idx = self.obj.axes[1]
245254
cols = self.obj.axes[2]
246255

256+
# by definition we are indexing on the 0th axis
257+
if is_panel:
258+
df = df.T
259+
247260
if idx.equals(df.index) and cols.equals(df.columns):
248261
return df.copy().values
262+
263+
# a passed in dataframe which is actually a transpose
264+
# of what is needed
265+
elif idx.equals(df.columns) and cols.equals(df.index):
266+
return df.T.copy().values
267+
249268
return df.reindex(idx, columns=cols).values
250269

251270
raise ValueError('Incompatible indexer with DataFrame')

pandas/tests/test_panel.py

+25
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,31 @@ def test_ix_frame_align(self):
655655
out = p.ix[0, [0, 1, 3, 5], -2:]
656656
assert_frame_equal(out, df.T.reindex([0, 1, 3, 5], p.minor_axis[-2:]))
657657

658+
# GH3830, panel assignent by values/frame
659+
for dtype in ['float64','int64']:
660+
661+
panel = Panel(np.arange(40).reshape((2,4,5)), items=['a1','a2'], dtype=dtype)
662+
df1 = panel.iloc[0]
663+
df2 = panel.iloc[1]
664+
665+
tm.assert_frame_equal(panel.loc['a1'], df1)
666+
tm.assert_frame_equal(panel.loc['a2'], df2)
667+
668+
# Assignment by Value Passes for 'a2'
669+
panel.loc['a2'] = df1.values
670+
tm.assert_frame_equal(panel.loc['a1'], df1)
671+
tm.assert_frame_equal(panel.loc['a2'], df1)
672+
673+
# Assignment by DataFrame Ok w/o loc 'a2'
674+
panel['a2'] = df2
675+
tm.assert_frame_equal(panel.loc['a1'], df1)
676+
tm.assert_frame_equal(panel.loc['a2'], df2)
677+
678+
# Assignment by DataFrame Fails for 'a2'
679+
panel.loc['a2'] = df2
680+
tm.assert_frame_equal(panel.loc['a1'], df1)
681+
tm.assert_frame_equal(panel.loc['a2'], df2)
682+
658683
def _check_view(self, indexer, comp):
659684
cp = self.panel.copy()
660685
obj = cp.ix[indexer]

0 commit comments

Comments
 (0)