Pandas:访问MultiIndex的级别以进行就地操作

时间:2014-07-04 10:17:10

标签: python pandas

我有一个具有多个属性的DataFrame(此处仅显示价格),以(位置,名称,类型)元组为索引编号:

df = pd.DataFrame.from_dict({'price': {
 ('DE', 'Coal', 'Stock'): 2,
 ('DE', 'Gas', 'Stock'): 4,
 ('DE', 'Elec', 'Demand'): 1,
 ('FR', 'Gas', 'Stock'): 5,
 ('FR', 'Solar', 'SupIm'): 0,
 ('FR', 'Wind', 'SupIm'): 0}})
df.index = pd.MultiIndex.from_tuples(df.index, names=['Sit', 'Com', 'Type'])

更具可读性:

                  price
Sit Com   Type
DE  Coal  Stock       2
    Elec  Demand      1
    Gas   Stock       4
FR  Gas   Stock       5
    Solar SupIm       0
    Wind  SupIm       0

我的问题:如何简洁地将price为真的所有行的属性Type == "Stock"相乘?

我只发现以下内容,涉及暂时重置索引以访问Type列。通过直接对索引进行比较,是否可以更直接地做同样的事情?

df = df.reset_index()
df.loc[df['Type'] == 'Stock', 'price'] *= 2
df.set_index(['Sit', 'Com', 'Type'])

我想写什么 - 有点:

df.loc[(:, :, 'Stock'), 'price'] *= 2

编辑(解决方案):感谢unutbu表示布尔屏蔽的想法,感谢Jeff指出了lexsorted问题,这让我可以修复我的代码,终于看起来像这样:

df.sortlevel(0, inplace=True)  # ensures that df is lexsorted
mask = (df.index.get_level_values('Type') == 'Stock')
df.loc[mask, 'price'] *= 2

1 个答案:

答案 0 :(得分:2)

In [23]: mask = (df.index.get_level_values(2) == 'Stock')

In [24]: df.loc[mask] *= 2

In [25]: df
Out[25]: 
                  price
Sit Com   Type         
DE  Coal  Stock       4
    Elec  Demand      1
    Gas   Stock       8
FR  Gas   Stock      10
    Solar SupIm       0
    Wind  SupIm       0