assignment to slice · Issue #5641 · pandas-dev/pandas (original) (raw)

In pandas version 0.81, this used to work:

import pandas as pd
import numpy as np
from pandas.tseries.offsets import *
from datetime import date


M_ASSETS=50
K_FACTORS=3

dates = pd.bdate_range(date(2013, 1, 1), date(2013, 1, 10))
factor_names=['F'+str(y) for y in xrange(1, K_FACTORS+1)]
asset_names = ['A'+str(y) for y in xrange(1, M_ASSETS+1)]

frames=[]
for dt in dates: 
    f=pd.DataFrame(np.random.randn(M_ASSETS, K_FACTORS),
                    index = pd.MultiIndex.from_tuples(zip([dt]*M_ASSETS, asset_names)), 
                                                    columns = factor_names)
    frames.append(f)


f=pd.concat(frames)

print "DataFrame for asset1\n", f.ix[:, "A1"]
print "DataFrame for factor1\n", f["F1"].unstack()
print "DataFrame for first date\n", f.ix[f.index.get_level_values(0)[0], :]

In pandas 0.11, however this same code gives the following error:


---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-1-09af79b5dd36> in <module>()
     22 f=pd.concat(frames)
     23 
---> 24 print "DataFrame for asset1\n", f.ix[:, "A1"]
     25 print "DataFrame for factor1\n", f["F1"].unstack()
     26 print "DataFrame for first date\n", f.ix[f.index.get_level_values(0)[0], :]

/mnt/bos-netapp01/epd/7.3-2_pandas0.10/lib/python2.7/site-packages/pandas/core/indexing.pyc in __getitem__(self, key)
     32                 pass
     33 
---> 34             return self._getitem_tuple(key)
     35         else:
     36             return self._getitem_axis(key, axis=0)

/mnt/bos-netapp01/epd/7.3-2_pandas0.10/lib/python2.7/site-packages/pandas/core/indexing.pyc in _getitem_tuple(self, tup)
    222                 continue
    223 
--> 224             retval = retval.ix._getitem_axis(key, axis=i)
    225 
    226         return retval

/mnt/bos-netapp01/epd/7.3-2_pandas0.10/lib/python2.7/site-packages/pandas/core/indexing.pyc in _getitem_axis(self, key, axis)
    362             if com.is_integer(key) and not _is_integer_index(labels):
    363                 return self._get_loc(key, axis=axis)
--> 364             return self._get_label(lab, axis=axis)
    365 
    366     def _getitem_iterable(self, key, axis=0):

/mnt/bos-netapp01/epd/7.3-2_pandas0.10/lib/python2.7/site-packages/pandas/core/indexing.pyc in _get_label(self, label, axis)
     46             return self.obj.xs(label, axis=axis, copy=False)
     47         except Exception:
---> 48             return self.obj.xs(label, axis=axis, copy=True)
     49 
     50     def _get_loc(self, key, axis=0):

/mnt/bos-netapp01/epd/7.3-2_pandas0.10/lib/python2.7/site-packages/pandas/core/frame.pyc in xs(self, key, axis, level, copy)
   2285 
   2286         if axis == 1:
-> 2287             data = self[key]
   2288             if copy:
   2289                 data = data.copy()

/mnt/bos-netapp01/epd/7.3-2_pandas0.10/lib/python2.7/site-packages/pandas/core/frame.pyc in __getitem__(self, key)
   1969                 raise ValueError('Cannot index using non-boolean DataFrame')
   1970         else:
-> 1971             return self._get_item_cache(key)
   1972 
   1973     def _getitem_array(self, key):

/mnt/bos-netapp01/epd/7.3-2_pandas0.10/lib/python2.7/site-packages/pandas/core/generic.pyc in _get_item_cache(self, item)
    532             return cache[item]
    533         except Exception:
--> 534             values = self._data.get(item)
    535             res = self._box_item_values(item, values)
    536             cache[item] = res

/mnt/bos-netapp01/epd/7.3-2_pandas0.10/lib/python2.7/site-packages/pandas/core/internals.pyc in get(self, item)
    882 
    883     def get(self, item):
--> 884         _, block = self._find_block(item)
    885         return block.get(item)
    886 

/mnt/bos-netapp01/epd/7.3-2_pandas0.10/lib/python2.7/site-packages/pandas/core/internals.pyc in _find_block(self, item)
   1014 
   1015     def _find_block(self, item):
-> 1016         self._check_have(item)
   1017         for i, block in enumerate(self.blocks):
   1018             if item in block:

/mnt/bos-netapp01/epd/7.3-2_pandas0.10/lib/python2.7/site-packages/pandas/core/internals.pyc in _check_have(self, item)
   1021     def _check_have(self, item):
   1022         if item not in self.items:
-> 1023             raise KeyError('no item named %s' % com.pprint_thing(item))
   1024 
   1025     def reindex_axis(self, new_axis, method=None, axis=0, copy=True):

KeyError: u'no item named A1'

DataFrame for asset1

Now I understand that the slicing changed, so if I use:

print "DataFrame for asset1\n", f.xs("A1", level=1)

it works:


DataFrame for asset1
                  F1        F2        F3
2013-01-01 -0.327087 -0.898145 -1.726459
2013-01-02  1.276976 -0.410213  1.124507
2013-01-03  0.575263  1.132212  0.172895
2013-01-04  0.704949 -0.681410  0.384713
2013-01-07 -0.033519 -0.598248  0.629885
2013-01-08 -0.065769  0.245913 -0.941165
2013-01-09  0.337986 -0.715003 -0.093851
2013-01-10  0.303433 -0.870952 -1.397974

Questions:

  1. Why does ix no longer work for this
  2. However, how to I assign to a slice:
    this does not work:
view = f.xs("A1", level=1, copy = False)
view = 10