@@ -36,21 +36,33 @@ def _getitem_xs(self, idx, axis=0):
36
36
return self .obj .xs (idx , axis = axis , copy = True )
37
37
38
38
def __setitem__ (self , key , value ):
39
+ # kludgetastic
40
+ ax = self .obj ._get_axis (0 )
41
+ if isinstance (ax , MultiIndex ):
42
+ try :
43
+ indexer = ax .get_loc (key )
44
+ self ._setitem_with_indexer (indexer , value )
45
+ return
46
+ except Exception :
47
+ pass
48
+
39
49
if isinstance (key , tuple ):
40
50
if len (key ) > self .ndim :
41
51
raise IndexingError ('only tuples of length <= %d supported' ,
42
52
self .ndim )
43
-
44
- keyidx = []
45
- for i , k in enumerate (key ):
46
- idx = self ._convert_to_indexer (k , axis = i )
47
- keyidx .append (idx )
48
- indexer = _maybe_convert_ix (* keyidx )
53
+ indexer = self ._convert_tuple (key )
49
54
else :
50
55
indexer = self ._convert_to_indexer (key )
51
56
52
57
self ._setitem_with_indexer (indexer , value )
53
58
59
+ def _convert_tuple (self , key ):
60
+ keyidx = []
61
+ for i , k in enumerate (key ):
62
+ idx = self ._convert_to_indexer (k , axis = i )
63
+ keyidx .append (idx )
64
+ return _maybe_convert_ix (* keyidx )
65
+
54
66
def _setitem_with_indexer (self , indexer , value ):
55
67
# also has the side effect of consolidating in-place
56
68
if self .obj ._is_mixed_type :
@@ -274,51 +286,73 @@ class _SeriesIndexer(_NDFrameIndexer):
274
286
"""
275
287
276
288
def __getitem__ (self , key ):
277
- op = self ._fancy_index (key , operation = 'get' )
278
- return op ()
279
-
280
- def __setitem__ (self , key , value ):
281
- op = self ._fancy_index (key , value , operation = 'set' )
282
- op ()
283
-
284
- def _fancy_index (self , key , value = None , operation = 'get' ):
285
- # going to great lengths to avoid code dup
286
- obj = self .obj
289
+ ax = self .obj .index
290
+ if isinstance (ax , MultiIndex ):
291
+ try :
292
+ # key = ax.get_loc(key)
293
+ return self ._get_default (key )
294
+ except Exception :
295
+ pass
287
296
288
- if operation == 'get' :
289
- def do_default ():
290
- return obj [key ]
297
+ if _isboolarr (key ):
298
+ self ._check_boolean_key (key )
299
+ elif isinstance (key , slice ):
300
+ key = self ._convert_slice (key )
301
+ elif _is_list_like (key ):
302
+ return self ._get_list_like (key )
303
+ return self ._get_default (key )
291
304
292
- def do_list_like ():
293
- if isinstance (obj .index , MultiIndex ):
294
- try :
295
- return obj [key ]
296
- except (KeyError , TypeError , IndexError ):
297
- pass
298
- return obj .reindex (key )
299
- else :
300
- def do_default ():
301
- obj [key ] = value
305
+ def __setitem__ (self , key , value ):
306
+ ax = self .obj .index
307
+ if isinstance (ax , MultiIndex ):
308
+ try :
309
+ key = ax .get_loc (key )
310
+ self ._set_default (key , value )
311
+ return
312
+ except Exception :
313
+ pass
302
314
303
- def do_list_like ():
304
- inds = obj .index .get_indexer (key )
305
- mask = inds == - 1
306
- if mask .any ():
307
- raise IndexingError ('Indices %s not found' % key [mask ])
308
- obj .put (inds , value )
309
- op = do_default
310
315
if _isboolarr (key ):
311
- if _is_series (key ):
312
- if not key .index .equals (obj .index ):
313
- raise IndexingError ('Cannot use boolean index with '
314
- 'misaligned or unequal labels' )
316
+ self ._check_boolean_key (key )
315
317
elif isinstance (key , slice ):
316
- if _is_label_slice (obj .index , key ):
317
- i , j = obj .index .slice_locs (key .start , key .stop )
318
- key = slice (i , j )
318
+ key = self ._convert_slice (key )
319
319
elif _is_list_like (key ):
320
- op = do_list_like
321
- return op
320
+ self ._set_list_like (key , value )
321
+ return
322
+ return self ._set_default (key , value )
323
+
324
+ def _check_boolean_key (self , key ):
325
+ if _is_series (key ):
326
+ if not key .index .equals (self .obj .index ):
327
+ raise IndexingError ('Cannot use boolean index with '
328
+ 'misaligned or unequal labels' )
329
+
330
+ def _convert_slice (self , key ):
331
+ if _is_label_slice (self .obj .index , key ):
332
+ i , j = self .obj .index .slice_locs (key .start , key .stop )
333
+ key = slice (i , j )
334
+ return key
335
+
336
+ def _get_default (self , key ):
337
+ return self .obj [key ]
338
+
339
+ def _get_list_like (self , key ):
340
+ if isinstance (self .obj .index , MultiIndex ):
341
+ try :
342
+ return self .obj [key ]
343
+ except (KeyError , TypeError , IndexError ):
344
+ pass
345
+ return self .obj .reindex (key )
346
+
347
+ def _set_default (self , key , value ):
348
+ self .obj [key ] = value
349
+
350
+ def _set_list_like (self , key , value ):
351
+ inds = self .obj .index .get_indexer (key )
352
+ mask = inds == - 1
353
+ if mask .any ():
354
+ raise IndexingError ('Indices %s not found' % key [mask ])
355
+ self .obj .put (inds , value )
322
356
323
357
def _is_series (obj ):
324
358
from pandas .core .series import Series
0 commit comments