Skip to content

Commit b571948

Browse files
committed
ENH: fix Series slicing on MultiIndex logic, get unit test suite to not error without LongPanel, still 6 test failures
1 parent ecd11e4 commit b571948

File tree

5 files changed

+56
-45
lines changed

5 files changed

+56
-45
lines changed

pandas/core/indexing.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,10 @@ class _SeriesIndexer(_NDFrameIndexer):
292292

293293
def __getitem__(self, key):
294294
ax = self.obj.index
295+
296+
if isinstance(key, slice):
297+
key = self._convert_slice(key)
298+
295299
if isinstance(ax, MultiIndex):
296300
try:
297301
# key = ax.get_loc(key)
@@ -302,7 +306,7 @@ def __getitem__(self, key):
302306
if _isboolarr(key):
303307
self._check_boolean_key(key)
304308
elif isinstance(key, slice):
305-
key = self._convert_slice(key)
309+
pass
306310
elif _is_list_like(key):
307311
return self._get_list_like(key)
308312
return self._get_default(key)

pandas/core/panel.py

-12
Original file line numberDiff line numberDiff line change
@@ -1160,18 +1160,6 @@ def _get_join_index(self, other, how):
11601160
WidePanel = Panel
11611161
LongPanel = DataFrame
11621162

1163-
def long_swapaxes(frame):
1164-
"""
1165-
Swap major and minor axes and reorder values to be grouped by
1166-
minor axis values
1167-
1168-
Returns
1169-
-------
1170-
DataFrame (new object)
1171-
"""
1172-
return frame.swaplevel(0, 1, axis=0)
1173-
1174-
11751163
def long_truncate(lp, before=None, after=None):
11761164
"""
11771165
Slice panel between two major axis values, return complete DataFrame

pandas/stats/plm.py

+25-23
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
import numpy as np
1212

13-
from pandas.core.panel import Panel, LongPanel
13+
from pandas.core.panel import Panel
1414
from pandas.core.frame import DataFrame
1515
from pandas.core.series import Series
1616
from pandas.core.sparse import SparsePanel
@@ -57,7 +57,7 @@ def log(self, msg):
5757
print msg
5858

5959
def _prepare_data(self):
60-
"""Cleans and converts input data into LongPanel classes.
60+
"""Cleans and stacks input data into DataFrame objects
6161
6262
If time effects is True, then we turn off intercepts and omit an item
6363
from every (entity and x) fixed effect.
@@ -77,8 +77,8 @@ def _prepare_data(self):
7777
x_filtered = self._add_dummies(x_filtered, cat_mapping)
7878

7979
if self._x_effects:
80-
x = x.filter(x.items - self._x_effects)
81-
x_filtered = x_filtered.filter(x_filtered.items - self._x_effects)
80+
x = x.drop(self._x_effects, axis=1)
81+
x_filtered = x_filtered.drop(self._x_effects, axis=1)
8282

8383
if self._time_effects:
8484
x_regressor = x.sub(x.mean(level=1), level=1)
@@ -115,7 +115,7 @@ def _filter_data(self):
115115
data = self._x_orig
116116
cat_mapping = {}
117117

118-
if isinstance(data, LongPanel):
118+
if isinstance(data, DataFrame):
119119
data = data.to_panel()
120120
else:
121121
if isinstance(data, Panel):
@@ -208,26 +208,28 @@ def _add_entity_effects(self, panel):
208208
-------
209209
LongPanel
210210
"""
211+
from pandas.core.panel import make_axis_dummies
212+
211213
if not self._entity_effects:
212214
return panel
213215

214216
self.log('-- Adding entity fixed effect dummies')
215217

216-
dummies = panel.get_axis_dummies(axis='minor')
218+
dummies = make_axis_dummies(panel, 'minor')
217219

218220
if not self._use_all_dummies:
219221
if 'entity' in self._dropped_dummies:
220222
to_exclude = str(self._dropped_dummies.get('entity'))
221223
else:
222-
to_exclude = dummies.items[0]
224+
to_exclude = dummies.columns[0]
223225

224-
if to_exclude not in dummies.items:
226+
if to_exclude not in dummies.columns:
225227
raise Exception('%s not in %s' % (to_exclude,
226-
dummies.items))
228+
dummies.columns))
227229

228230
self.log('-- Excluding dummy for entity: %s' % to_exclude)
229231

230-
dummies = dummies.filter(dummies.items - [to_exclude])
232+
dummies = dummies.filter(dummies.columns - [to_exclude])
231233

232234
dummies = dummies.add_prefix('FE_')
233235
panel = panel.join(dummies)
@@ -242,6 +244,8 @@ def _add_categorical_dummies(self, panel, cat_mappings):
242244
-------
243245
LongPanel
244246
"""
247+
from pandas.core.panel import make_dummies
248+
245249
if not self._x_effects:
246250
return panel
247251

@@ -250,7 +254,7 @@ def _add_categorical_dummies(self, panel, cat_mappings):
250254
for effect in self._x_effects:
251255
self.log('-- Adding fixed effect dummies for %s' % effect)
252256

253-
dummies = panel.get_dummies(effect)
257+
dummies = make_dummies(panel, effect)
254258

255259
val_map = cat_mappings.get(effect)
256260
if val_map:
@@ -263,15 +267,15 @@ def _add_categorical_dummies(self, panel, cat_mappings):
263267
if val_map:
264268
mapped_name = val_map[to_exclude]
265269
else:
266-
to_exclude = mapped_name = dummies.items[0]
270+
to_exclude = mapped_name = dummies.columns[0]
267271

268-
if mapped_name not in dummies.items: # pragma: no cover
272+
if mapped_name not in dummies.columns: # pragma: no cover
269273
raise Exception('%s not in %s' % (to_exclude,
270-
dummies.items))
274+
dummies.columns))
271275

272276
self.log('-- Excluding dummy for %s: %s' % (effect, to_exclude))
273277

274-
dummies = dummies.filter(dummies.items - [mapped_name])
278+
dummies = dummies.filter(dummies.columns - [mapped_name])
275279
dropped_dummy = True
276280

277281
dummies = _convertDummies(dummies, cat_mappings.get(effect))
@@ -301,7 +305,7 @@ def _beta_raw(self):
301305

302306
@cache_readonly
303307
def beta(self):
304-
return Series(self._beta_raw, index=self._x.items)
308+
return Series(self._beta_raw, index=self._x.columns)
305309

306310
@cache_readonly
307311
def _df_model_raw(self):
@@ -402,9 +406,7 @@ def y_fitted(self):
402406
def _unstack_vector(self, vec, index=None):
403407
if index is None:
404408
index = self._y_trans.index
405-
panel = LongPanel(vec.reshape((len(vec), 1)), index=index,
406-
columns=['dummy'])
407-
409+
panel = DataFrame(vec, index=index, columns=['dummy'])
408410
return panel.to_panel()['dummy']
409411

410412
def _unstack_y(self, vec):
@@ -426,7 +428,7 @@ def _nobs(self):
426428
def _convertDummies(dummies, mapping):
427429
# cleans up the names of the generated dummies
428430
new_items = []
429-
for item in dummies.items:
431+
for item in dummies.columns:
430432
if not mapping:
431433
var = str(item)
432434
if isinstance(item, float):
@@ -437,7 +439,7 @@ def _convertDummies(dummies, mapping):
437439
# renames the dummies if a conversion dict is provided
438440
new_items.append(mapping[int(item)])
439441

440-
dummies = LongPanel(dummies.values, index=dummies.index,
442+
dummies = DataFrame(dummies.values, index=dummies.index,
441443
columns=new_items)
442444

443445
return dummies
@@ -757,8 +759,8 @@ def _var_beta_panel(y, x, beta, xx, rmse, cluster_axis,
757759
columns=['resid'])
758760

759761
if cluster_axis == 1:
760-
x = x.swapaxes()
761-
resid = resid.swapaxes()
762+
x = x.swaplevel(0, 1).sortlevel(0)
763+
resid = resid.swaplevel(0, 1).sortlevel(0)
762764

763765
m = group_agg(x.values * resid.values, x.index._bounds,
764766
lambda x: np.sum(x, axis=0))

pandas/stats/tests/test_ols.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -392,18 +392,18 @@ def testFiltering(self):
392392
result = ols(y=self.panel_y2, x=self.panel_x2)
393393

394394
x = result._x
395-
index = [x.major_axis[i] for i in x.major_labels]
395+
index = x.index.get_level_values(0)
396396
index = Index(sorted(set(index)))
397397
exp_index = Index([datetime(2000, 1, 1), datetime(2000, 1, 3)])
398-
self.assertTrue(exp_index.equals(index))
398+
self.assertTrue;(exp_index.equals(index))
399399

400-
index = [x.minor_axis[i] for i in x.minor_labels]
400+
index = x.index.get_level_values(1)
401401
index = Index(sorted(set(index)))
402402
exp_index = Index(['A', 'B'])
403403
self.assertTrue(exp_index.equals(index))
404404

405405
x = result._x_filtered
406-
index = [x.major_axis[i] for i in x.major_labels]
406+
index = x.index.get_level_values(0)
407407
index = Index(sorted(set(index)))
408408
exp_index = Index([datetime(2000, 1, 1),
409409
datetime(2000, 1, 3),
@@ -424,7 +424,7 @@ def testFiltering(self):
424424
[12, 21, 1]]
425425
assert_almost_equal(exp_x_filtered, result._x_filtered.values)
426426

427-
self.assertTrue(result._x_filtered.major_axis.equals(
427+
self.assertTrue(result._x_filtered.index.levels[0].equals(
428428
result.y_fitted.index))
429429

430430
def test_wls_panel(self):
@@ -500,7 +500,7 @@ def testWithXEffects(self):
500500
assert_almost_equal(result._x.values, exp_x)
501501

502502
exp_index = Index(['x1_30', 'x1_9', 'x2', 'intercept'])
503-
self.assertTrue(exp_index.equals(result._x.items))
503+
self.assertTrue(exp_index.equals(result._x.columns))
504504

505505
# _check_non_raw_results(result)
506506

@@ -513,7 +513,7 @@ def testWithXEffectsAndDroppedDummies(self):
513513
assert_almost_equal(result._x.values, exp_x)
514514

515515
exp_index = Index(['x1_6', 'x1_9', 'x2', 'intercept'])
516-
self.assertTrue(exp_index.equals(result._x.items))
516+
self.assertTrue(exp_index.equals(result._x.columns))
517517

518518
# _check_non_raw_results(result)
519519

@@ -526,7 +526,7 @@ def testWithXEffectsAndConversion(self):
526526
assert_almost_equal(result._x.values, exp_x)
527527

528528
exp_index = Index(['x1_B', 'x1_C', 'x2_baz', 'x2_foo', 'intercept'])
529-
self.assertTrue(exp_index.equals(result._x.items))
529+
self.assertTrue(exp_index.equals(result._x.columns))
530530

531531
# _check_non_raw_results(result)
532532

@@ -540,7 +540,7 @@ def testWithXEffectsAndConversionAndDroppedDummies(self):
540540
assert_almost_equal(result._x.values, exp_x)
541541

542542
exp_index = Index(['x1_B', 'x1_C', 'x2_bar', 'x2_baz', 'intercept'])
543-
self.assertTrue(exp_index.equals(result._x.items))
543+
self.assertTrue(exp_index.equals(result._x.columns))
544544

545545
# _check_non_raw_results(result)
546546

pandas/tests/test_multilevel.py

+17
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,23 @@ def test_getitem_toplevel(self):
218218
assert_frame_equal(result, expected)
219219
assert_frame_equal(result, result2)
220220

221+
def test_getitem_slice_integers(self):
222+
index = MultiIndex(levels=[[0, 1, 2], [0, 2]],
223+
labels=[[0, 0, 1, 1, 2, 2],
224+
[0, 1, 0, 1, 0, 1]])
225+
226+
frame = DataFrame(np.random.randn(len(index), 4), index=index,
227+
columns=['a', 'b', 'c', 'd'])
228+
res = frame.ix[1:2]
229+
exp = frame[2:]
230+
assert_frame_equal(res, exp)
231+
232+
series = Series(np.random.randn(len(index)), index=index)
233+
234+
res = series.ix[1:2]
235+
exp = series[2:]
236+
assert_series_equal(res, exp)
237+
221238
def test_getitem_int(self):
222239
levels = [[0, 1], [0, 1, 2]]
223240
labels = [[0, 0, 0, 1, 1, 1], [0, 1, 2, 0, 1, 2]]

0 commit comments

Comments
 (0)