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,但是在将其存储回来时,我尝试过的所有选项似乎都不起作用。我想这个问题与拥有“整数”标签有关(在第二和第三拉维尔 - 开始-停止)。我尝试了以下选项/方法但没有任何成功

    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))]

我收到以下错误 -

TypeError:不可散列的类型:'numpy.ndarray'

这里的主要目的是仅对 master_df 的一小块进行操作,并将这些结果存储回 master_df 中的原始位置。我尝试使用更新方法,但是实现此目的的任何其他替代方法都可以。

4

5 回答 5

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
于 2013-03-05T00:09:08.293 回答
1

sub_df具有与 相同的索引很重要master_df

获得正确索引的一种方法是使用get_loc

sub_df = df[df.index.get_loc(('B1', 1, 2))]
# operations not changing index
master_df.update(sub_df)
于 2013-03-04T12:26:48.737 回答
0

对于您给出的示例(选择 ('B1', 1, 2, ...)),您可以使用 xs iso ix。与 ix 相比,xs 可以在使用标签时返回数据视图(有关 ix 返回视图/副本的更多详细信息,请参阅文档)。在下面的示例中,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
于 2013-03-06T20:34:28.497 回答
0

谢谢大家的帮助。最后,我从 2 级和 3 级的数字索引切换到字符索引,现在一切正常(这也有助于在级别上进行适当的排序,我想这会让事情变得更加明确。)

于 2013-03-05T12:35:55.967 回答
0

在 0.13 中,参数 'drop_level' 已添加到 'xs' 中,这样可以解决您的问题,因为所有索引级别都将出现在 sub_df 中:

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

现在合并将起作用。

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

参考:使用熊猫的“大数据”工作流程

于 2014-02-21T15:14:02.237 回答