@@ -36,11 +36,6 @@ 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
- # also has the side effect of consolidating in-place
40
- if self .obj ._is_mixed_type :
41
- raise IndexingError ('setting on mixed-type frames not '
42
- 'yet supported' )
43
-
44
39
if isinstance (key , tuple ):
45
40
if len (key ) > self .ndim :
46
41
raise IndexingError ('only tuples of length <= %d supported' ,
@@ -54,7 +49,31 @@ def __setitem__(self, key, value):
54
49
else :
55
50
indexer = self ._convert_to_indexer (key )
56
51
57
- self .obj .values [indexer ] = value
52
+ self ._setitem_with_indexer (indexer , value )
53
+
54
+ def _setitem_with_indexer (self , indexer , value ):
55
+ # also has the side effect of consolidating in-place
56
+ if self .obj ._is_mixed_type :
57
+ if not isinstance (indexer , tuple ):
58
+ indexer = self ._tuplify (indexer )
59
+
60
+ het_axis = self .obj ._het_axis
61
+ het_idx = indexer [het_axis ]
62
+
63
+ if isinstance (het_idx , (int , long )):
64
+ het_idx = [het_idx ]
65
+
66
+ if not np .isscalar (value ):
67
+ raise IndexingError ('setting on mixed-type frames only '
68
+ 'allowedwith scalar values' )
69
+
70
+ plane_indexer = indexer [:het_axis ] + indexer [het_axis + 1 :]
71
+ item_labels = self .obj ._get_axis (het_axis )
72
+ for item in item_labels [het_idx ]:
73
+ data = self .obj [item ]
74
+ data .values [plane_indexer ] = value
75
+ else :
76
+ self .obj .values [indexer ] = value
58
77
59
78
def _getitem_tuple (self , tup ):
60
79
# a bit kludgy
@@ -205,6 +224,11 @@ def _convert_to_indexer(self, obj, axis=0):
205
224
return obj
206
225
return index .get_loc (obj )
207
226
227
+ def _tuplify (self , loc ):
228
+ tup = [slice (None , None ) for _ in range (self .ndim )]
229
+ tup [0 ] = loc
230
+ return tuple (tup )
231
+
208
232
def _get_slice_axis (self , slice_obj , axis = 0 ):
209
233
obj = self .obj
210
234
0 commit comments