如何更新MultiIndexed pandas DataFrame的子集

我正在使用MultiIndexed pandas DataFrame,并希望将DataFrame的子集乘以一定数量.

它与this相同,但具有MultiIndex.

>>> d = pd.DataFrame({'year':[2008,2008,2008,2008,2009,2009,2009,2009], 
                      'flavour':['strawBerry','strawBerry','banana','banana',
                      'strawBerry','strawBerry','banana','banana'],
                      'day':['sat','sun','sat','sun','sat','sun','sat','sun'],
                      'sales':[10,12,22,23,11,13,23,24]})

>>> d = d.set_index(['year','flavour','day'])                  

>>> d
                     sales
year flavour    day       
2008 strawBerry sat     10
                sun     12
     banana     sat     22
                sun     23
2009 strawBerry sat     11
                sun     13
     banana     sat     23
                sun     24

到现在为止还挺好.但是,让我说我发现星期六的数字只是他们应该的一半!我想把所有的销售额乘以2.

我的第一次尝试是:

sat = d.xs('sat', level='day')
sat = sat * 2
d.update(sat)

但是这不起作用,因为变量sat已经丢失了索引的日级别:

>>> sat
                 sales
year flavour          
2008 strawBerry     20
     banana         44
2009 strawBerry     22
     banana         46

所以熊猫不知道如何将新的销售数据加入旧的数据框架.

快速刺伤了:

>>> sat = d.xs('sat', level='day', copy=False)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python27\lib\site-packages\pandas\core\frame.py", line 2248, in xs
    raise ValueError('Cannot retrieve view (copy=False)')
ValueError: Cannot retrieve view (copy=False)

我不知道那个错误意味着什么,但我觉得我正在用一个小山丘制造一座山.有谁知道这样做的正确方法

提前致谢,

解决方法:

注意:即将发布0.13 a drop_level argument has been added to xs(感谢这个问题!):

In [42]: df.xs('sat', level='day', drop_level=False)
Out[42]:
                     sales
year flavour    day
2008 strawBerry sat     10

另一种选择是使用select(它提取相同数据的子DataFrame(副本),即它具有相同的索引,因此可以正确更新):

In [11]: d.select(lambda x: x[2] == 'sat') * 2
Out[11]:
                     sales
year flavour    day
2008 strawBerry sat     20
     banana     sat     44
2009 strawBerry sat     22
     banana     sat     46

In [12]: d.update(d.select(lambda x: x[2] == 'sat') * 2)

另一种选择是使用申请:

In [21]: d.apply(lambda x: x*2 if x.name[2] == 'sat' else x, axis=1)

另一种选择是使用get_level_values(这可能是最有效的方法):

In [22]: d[d.index.get_level_values('day') == 'sat'] *= 2

另一种选择是将“日”级别提升为列,然后使用“应用”.

相关文章

转载:一文讲述Pandas库的数据读取、数据获取、数据拼接、数...
Pandas是一个开源的第三方Python库,从Numpy和Matplotlib的基...
整体流程登录天池在线编程环境导入pandas和xrld操作EXCEL文件...
 一、numpy小结             二、pandas2.1为...
1、时间偏移DateOffset对象DateOffset类似于时间差Timedelta...
1、pandas内置样式空值高亮highlight_null最大最小值高亮背景...