Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何更新多索引数据帧的子集_Python_Pandas - Fatal编程技术网

Python 如何更新多索引数据帧的子集

Python 如何更新多索引数据帧的子集,python,pandas,Python,Pandas,我正在使用一个多索引的数据帧,并希望将数据帧的子集乘以某个数字 它与相同,但具有多索引 >>> d = pd.DataFrame({'year':[2008,2008,2008,2008,2009,2009,2009,2009], 'flavour':['strawberry','strawberry','banana','banana', 'strawberry','strawberry

我正在使用一个多索引的数据帧,并希望将数据帧的子集乘以某个数字

它与相同,但具有多索引

>>> 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
到目前为止,一切顺利。但假设我发现所有周六的数据都只是应该的一半!我想把sat的销售额乘以2

我的第一次尝试是:

sat = d.xs('sat', level='day')
sat = sat * 2
d.update(sat)
但这不起作用,因为变量
sat
已经失去了索引的
day
级别:

>>> 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)
>sat=d.xs('sat',level='day',copy=False)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“C:\Python27\lib\site packages\pandas\core\frame.py”,第2248行,xs格式
raise VALUERROR('无法检索视图(copy=False)')
ValueError:无法检索视图(copy=False)
我不知道那个错误是什么意思,但我觉得我是小题大做。有人知道这样做的正确方法吗

提前感谢,,
Rob

注意:在即将发布的0.13版本中(由于这个问题!):

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

另一个选项是使用应用程序:

In [21]: d.apply(lambda x: x*2 if x.name[2] == 'sat' else x, axis=1)
另一种选择是使用
获取级别值
(这可能是其中最有效的方法):

另一个选项是将“日”级别提升为列,然后使用“应用”。

详细的多索引说明 您可以使用
.loc
索引器从具有多索引的数据帧中选择数据子集。假设我们有原始问题的数据:

                     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
此数据框在其索引中有3个级别,每个级别都有一个名称(
年份
风味
日期
)。这些级别还隐式指定了从外部以0开始的整数位置。因此,
水平可参考为
0
风味
1
2

从标高0中选择-最外层标高 级别
0
是最容易选择的级别。例如,如果我们只想选择2008年,我们可以执行以下操作:

df.loc[2008]

                sales
flavour    day       
strawberry sat     10
           sun     12
banana     sat     22
           sun     23
df.loc[([2008, 2009], 'banana', ('sat','sun'))]

                  sales
year flavour day       
2008 banana  sat     22
             sun     23
2009 banana  sat     23
             sun     24
                     sales
year flavour    day       
2008 strawberry sat     10
     banana     sat     22
2009 strawberry sat     11
     banana     sat     23
这会降低外部索引级别。如果要保持外部级别,可以将选择作为列表(或切片)传递:

从其他级别进行选择 从级别0以外的任何级别进行选择更为复杂。让我们首先选择一个特定的组合,如2008年、香蕉年和sat年。为此,将组合作为元组传递给
.loc

df.loc[(2008, 'banana', 'sat')]

sales    22
Name: (2008, banana, sat), dtype: int64
我总是像上面那样使用括号,但Python会自动将任何逗号分隔的值集解释为元组,因此下面将得到相同的结果:

df.loc[2008, 'banana', 'sat']
所有级别都被删除,并返回一系列。我们可以通过在列表中传递元组来保持级别:

df.loc[[(2008, 'banana', 'sat')]]

                  sales
year flavour day       
2008 banana  sat     22
从特定级别选择多个值 上一个示例从每个级别进行了单个选择。可以使用列表来包含所需级别的所有值。例如,如果我们想选择2008年和2009年的所有行,在周六和周日,我们可以执行以下操作:

df.loc[2008]

                sales
flavour    day       
strawberry sat     10
           sun     12
banana     sat     22
           sun     23
df.loc[([2008, 2009], 'banana', ('sat','sun'))]

                  sales
year flavour day       
2008 banana  sat     22
             sun     23
2009 banana  sat     23
             sun     24
                     sales
year flavour    day       
2008 strawberry sat     10
     banana     sat     22
2009 strawberry sat     11
     banana     sat     23
同样,您不必将整个选择用paraenthese来表示元组,只需执行以下操作:

df.loc[[2008, 2009], 'banana', ('sat','sun')]
从特定级别选择所有值。 您可能希望选择特定级别的所有值。例如,让我们试着选择所有年份、所有口味和星期六。您可能认为以下方法可行:

df.loc[:, :, 'sat']
但是,这遇到了“太多索引器的索引器”。有三种不同的方法可以选择特定级别的所有值

  • df.loc[(片(无),片(无),'sat'),:]
  • df.loc(axis=0)[:,:,'sat']
  • df.loc[pd.indexlice[:,:,'sat'],:]
这三种方法都会产生以下效果:

df.loc[2008]

                sales
flavour    day       
strawberry sat     10
           sun     12
banana     sat     22
           sun     23
df.loc[([2008, 2009], 'banana', ('sat','sun'))]

                  sales
year flavour day       
2008 banana  sat     22
             sun     23
2009 banana  sat     23
             sun     24
                     sales
year flavour    day       
2008 strawberry sat     10
     banana     sat     22
2009 strawberry sat     11
     banana     sat     23

是的,这是一个有效的解决方案,但是使用
lambda
s来完成这样一个(看似)简单的任务感觉是错误的。SQL等价物是更新表集合col=col*2,其中day='sat'
。我想知道
xs
是否应该包含一个选项来保持索引级别处于选中状态。@LondonRob是的(更新是我不太喜欢的事情,lambda也不太糟糕),确实如此。我想知道同样的事情,也许值得作为一个问题添加(如果我们很快,它可能在下周的0.12中)。肯定还有改进的余地。作为旁白,使用多索引似乎会让一切变得更加困难。我真的不知道这会让什么更容易!!哈哈!对好吧,那太神奇了,但我想开发者们会争先恐后地完成工作,而不是想添加新的功能。@LondonRob
d[d.index.get_level\u values('day')=='sat']*=2
我认为更快了……对于那些正在寻找更详细的多索引解决方案的用户来说,如果您有兴趣了解更多关于切片和过滤多索引数据帧的信息,请查看我的帖子:.
df.loc(axis=0)[:,:,'sat']
Woah。。。。可以您能给我解释一下或给我指一下有关使用轴参数和
loc
的文档吗+1@ScottBoston是的,我也不知道,直到我死了。你得从那里往下看一页左右。看起来是从5月份开始加的,2014@TedPetrou请您添加允许在特定级别设置所有值的选择器好吗?我正在尝试
df.loc[('2008','banana','sat'),'sales']
并得到以下错误:keyrerror:“Passing list likes to.loc或[]不再支持任何缺少的标签。缺少以下标签:索引(['00',dtype='object',name='master\u零件号')。请参阅“