2013-03-04 48 views
2

我正在使用具有混合索引标签的多索引数据框,即第一级包含字符串标签,第二和第三级为整数标签,第四级标签为日期。 数据框看起来像下面(master_df)使用具有整数标签的多索引索引部分更新数据帧

          X1 X2 X3 
bucket  Start Stop  Date   
B1    1  1   1/3/2000 2 2 3 
           1/4/2000 4 3 3 
B1    1  2   1/3/2000 4 2 3 
           1/4/2000 6 2 2 

我要拿出sub_df为master_df.ix [ 'B1',1,2 ,:],做sub_df一些操作,并将其存储回master_df在同一地点。我能够使用各种方法取出sub_df,但是当涉及到存储它时,我尝试过的所有选项似乎都不起作用。我想这个问题与'Integer'标签有关(在第2和第3层 - 启动 - 停止)。我曾尝试以下选项/方法没有任何成功

sub_df = master_df.ix['B1'].ix[1].ix[2] 

    #do some operations on sub_df 

    master_df.xs('B1').xs(1).xs(2).update(sub_df) 

    master_df.ix['B1'].ix[1].ix[2].update(sub_df) 

    merge(master_df.ix['B1',1,2,:],sub_df) 

以上操作的反映master_df变化(我没有收到任何错误讯息无论是。)

您能否提供适当的方式做到这一点?

更新:

sub_df和master_df不具有相同的索引上sub_df操作只期望日期索引。 sub_df看起来像下面。

  X1 X2 X3 
Date   
1/3/2000 2 2 3 
1/4/2000 4 3 3 

如果我尝试

sub_df = master_df[master_df.index.get_loc(('B1', 1, 2))] 

我获得以下错误 -

类型错误:unhashable类型: 'numpy.ndarray'

这里主要目的是为了操作上只有很小的块master_df并将这些结果存回master_df的原始位置。我尝试过使用更新方法,但是为了实现这个目的,还有其他的选择。

+0

你可以检查是否'sub_df'具有指数相同'master_df'?因为[doc](http://pandas.pydata.org/pandas-docs/stable/merging.html#merging-together-values-within-series-or-dataframe-columns)提到类似“两个类似索引的(或类似索引)“更新”方法的“DataFrames或Series”。 – herrfz 2013-03-04 12:17:32

回答

1

重要的是sub_dfmaster_df具有相同的索引。以获得正确的索引

一种方法是使用get_loc

sub_df = df[df.index.get_loc(('B1', 1, 2))] 
# operations not changing index 
master_df.update(sub_df) 
2

这并不完全解决你的问题,但我这可能 提供一些启示

这里有一个方法来设置值直接

In [75]: df 
Out[75]: 
    bucket start stop    date x1 x2 x3 
0  B1  1  1 2000-10-03 00:00:00 2 2 3 
1  B1  1  1 2000-01-04 00:00:00 4 3 3 
2  B1  1  2 2000-01-03 00:00:00 4 2 3 
3  B1  1  2 2000-01-04 00:00:00 6 2 2 

In [76]: df2 = df.set_index(['bucket','start','stop']) 

In [77]: df2 
Out[77]: 
           date x1 x2 x3 
bucket start stop         
B1  1  1 2000-10-03 00:00:00 2 2 3 
      1 2000-01-04 00:00:00 4 3 3 
      2 2000-01-03 00:00:00 4 2 3 
      2 2000-01-04 00:00:00 6 2 2 

In [78]: df2.ix[('B1',1,2)].ix[:,'x1'] = 5 

In [79]: df2 
Out[79]: 
           date x1 x2 x3 
bucket start stop         
B1  1  1 2000-10-03 00:00:00 2 2 3 
      1 2000-01-04 00:00:00 4 3 3 
      2 2000-01-03 00:00:00 5 2 3 
      2 2000-01-04 00:00:00 5 2 2 

这里的另一种方式,你选择了一系列具有多指标,对其进行修改, 然后将其分配回去(仅适用于系列)。

In [89]: df2.ix[:,'x1'] 
Out[89]: 
bucket start stop 
B1  1  1  2 
       1  4 
       2  4 
       2  6 
Name: x1, dtype: int64 

In [90]: new_s = df2.ix[:,'x1'].copy() 

In [91]: new_s 
Out[91]: 
bucket start stop 
B1  1  1  2 
       1  4 
       2  4 
       2  6 
Name: x1, dtype: int64 

# can also do a more complicated selctor than the 0th row 
In [92]: new_s[0] = 5 

In [93]: new_s 
Out[93]: 
bucket start stop 
B1  1  1  5 
       1  4 
       2  4 
       2  6 
Name: x1, dtype: int64 

In [94]: df2.ix[:,'x1'] = new_s 

In [95]: df2 
Out[95]: 
           date x1 x2 x3 
bucket start stop         
B1  1  1 2000-10-03 00:00:00 5 2 3 
      1 2000-01-04 00:00:00 4 3 3 
      2 2000-01-03 00:00:00 4 2 3 
      2 2000-01-04 00:00:00 6 2 2 

这里是您可以在0.11

# this is sessentially saying give me the first 2 rows (equivalent 
# to selecting via complicated tuple) 
In [107]: df2.iloc[0:2,:] 
Out[107]: 
           date x1 x2 x3 
bucket start stop         
B1  1  1 2000-10-03 00:00:00 10 2 3 
      1 2000-01-04 00:00:00 4 3 3 

In [108]: df2.iloc[0:2,:].loc[:,'x1'] 
Out[108]: 
bucket start stop 
B1  1  1  10 
       1  4 
Name: x1, dtype: int64 

In [109]: df2.iloc[0:2,:].loc[:,'x1'] = 5 

In [110]: df2 
Out[110]: 
           date x1 x2 x3 
bucket start stop         
B1  1  1 2000-10-03 00:00:00 5 2 3 
      1 2000-01-04 00:00:00 5 3 3 
      2 2000-01-03 00:00:00 4 2 3 
      2 2000-01-04 00:00:00 6 2 2 
0

感谢所有帮助做什么。最后,我在2级和3级转换为数字索引的特性索引,现在情况正常(这也有助于在级别上进行适当的排序,这是我认为使事情更明确。)

0

对于您给出的示例(选择('B1',1,2,...)),您可以使用xs iso ix。与ix相比,xs可以在使用标签时返回数据视图(有关ix返回视图/副本的更多详细信息,请参阅docs)。 在下面的示例中,sub_df的列X1是变化,这也会影响master_df。

In [48]: master_df 
Out[48]: 
           X1 X2 X3 
bucket Start Stop Date     
B1  1  1 2000-01-03 2 2 3 
        2000-01-04 4 3 3 
      2 2000-01-03 4 2 3 
        2000-01-04 6 2 2 

In [49]: sub_df = master_df.xs(['B1', 1, 2], copy=False) 

In [50]: sub_df 
Out[50]: 
      X1 X2 X3 
Date     
2000-01-03 4 2 3 
2000-01-04 6 2 2 

In [51]: sub_df.X1 -= 4 

In [52]: sub_df 
Out[52]: 
      X1 X2 X3 
Date     
2000-01-03 0 2 3 
2000-01-04 2 2 2 

In [53]: master_df 
Out[53]: 
           X1 X2 X3 
bucket Start Stop Date     
B1  1  1 2000-01-03 2 2 3 
        2000-01-04 4 3 3 
      2 2000-01-03 0 2 3 
        2000-01-04 2 2 2 
0

在0.13参数 'drop_level' 已被添加到 'XS',以便将解决问题,因为所有的索引级别将存在于sub_df:

sub_df = master_df.xs([ 'B1' ,1,2],level = ['bucket','Start','Stop'],drop_level = False)

现在合并会生效。

还没有尝试过,但它应该工作。

裁判:"Large data" work flows using pandas