If you have a Panel with a MultiIndex, you can read but not write to it with .ix
(same with .loc
).
Before 0.13 I would normally do something like pn[item].ix[a, b][stuff] = values
, surprisingly it used to work (now it spits out a SettingWithCopyWarning
but still kinda works).
So what are the valid options in 0.13?
>>> df = pd.DataFrame([1] * 3, pd.MultiIndex.from_tuples(zip(range(3), range(3))))
>>> df
0
0 0 1
1 1 1
2 2 1
[3 rows x 1 columns]
>>> pn = pd.Panel(dict((k, df.copy() * k) for k in xrange(2)))
>>> pn
<class 'pandas.core.panel.Panel'>
Dimensions: 2 (items) x 3 (major_axis) x 1 (minor_axis)
Items axis: 0 to 1
Major_axis axis: (0, 0) to (2, 2)
Minor_axis axis: 0 to 0
>>> pn.ix[1, (0, 0), 0]
1
>>> pn.ix[1, (0, 0), 0] = 1
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-64-f48c3a7f93c3> in <module>()
----> 1 pn.ix[1, (0, 0), 0] = 1
/home/smirnov/anaconda/lib/python2.7/site-packages/pandas-0.13.1-py2.7-linux-x86_64.egg/pandas/core/indexing.pyc in __setitem__(self, key, value)
96 indexer = self._convert_to_indexer(key, is_setter=True)
97
---> 98 self._setitem_with_indexer(indexer, value)
99
100 def _has_valid_type(self, k, axis):
/home/smirnov/anaconda/lib/python2.7/site-packages/pandas-0.13.1-py2.7-linux-x86_64.egg/pandas/core/indexing.pyc in _setitem_with_indexer(self, indexer, value)
299 obj = self.obj[item]
300 index = obj.index
--> 301 idx = indexer[:info_axis][0]
302 try:
303 if idx in index:
IndexError: tuple index out of range
> /home/smirnov/anaconda/lib/python2.7/site-packages/pandas-0.13.1-py2.7-linux-x86_64.egg/pandas/core/indexing.py(301)_setitem_with_indexer()
300 index = obj.index
--> 301 idx = indexer[:info_axis][0]
302 try:
Comment From: jreback
this was completely untested so suprised it used to work
Comment From: TomAugspurger
Possibly related: https://github.com/pydata/pandas/issues/5773
I look at the code but didn't make any progress on a fix.
Comment From: aldanor
Wondering what the current workaround would be? Now that we are more strict on the entire view/copy thing (cause previously you could just do something cheap like a .ix.ix.ix
and it worked somewhy).
Idk how many people actually use panels but this bug looks pretty serious.
Comment From: jreback
I am not sure this is a bug, but rather a specification issue. right now the indexers cannot differentiate between a multi-index and another axis easily (if at all, sometimes its completely ambiguous)
you can use iloc
; I would simply not use a multi-index on a panel
Comment From: aldanor
@jreback I guess the reference here should be how dataframes work: df.ix[(a, b), x:y] = value
works fine right?
Comment From: jreback
yep
Comment From: aldanor
Yea, so as a consequence panel[item].ix[(a, b), x:y] = value
also works, but panel.ix[item, (a, b), x:y] = value
doesn't.
Comment From: jreback
you can do that as long as its a single-dtyped Panel....the other is prob a bug and will get to it at some point
Comment From: jreback
closing as Panels are deprecated