FooBar FooBar - 29 days ago 7
Python Question

Round columns based on second level of MultiColumn

I have a table which looks like this:

>>> df.head()
Out[13]:
v u
init change integral init change
foo bar
baseline NaN 0.025054 0.858122 0.017930 0.048435 1.091943
a 10.0 0.025042 0.856307 0.017546 0.047815 1.100351
50.0 0.025008 0.856681 0.010052 0.048252 1.056658
b 1.0 0.025045 0.858044 0.015635 0.047135 1.091384
2.0 0.025048 0.855388 0.016115 0.047324 1.087964


Now I would like to select columns based on the label of the second level of the column, and round them.

I can access them using
xs
:
df.xs('init', 1, 1)
. However, I naturally cannot use
xs
to replace the values:

>>> df.xs('init', 1, 1) = df.xs('init', 1, 1).round(decimals=3)
File "<ipython-input-12-47c16e5011a3>", line 1
df.xs('init', 1, 1) = df.xs('init', 1, 1).round(decimals=3)
SyntaxError: can't assign to function call


What's the way to go here?

Answer

consider the dataframe:

df = pd.DataFrame(np.arange(8).reshape(2, 4),
                  ['a', 'b'],
                  pd.MultiIndex.from_product([['A', 'B'], ['One', 'Two']]))

df

enter image description here

Use pd.IndexSlice

df.loc[:, pd.IndexSlice[:, 'Two']] *= 3

df

enter image description here

In this case pd.IndexSlice[:, 'Two'] is specifying all elements from the first level and 'Two' from the second level. Using loc allows us to assign to df.