pandas - 更改第二级索引的值以显示第一级索引中的位置

时间:2014-07-14 17:38:22

标签: python pandas multi-index

如何从

更改二级索引的值
                           PRICE  
TIMESTAMP           HSEC                            
2013-03-15 09:00:29  1     34.480 
2013-03-15 09:00:30  0     34.470  
                     3     34.485  
2013-03-15 09:00:31  0     34.495   
2013-03-15 09:00:35  0     34.485   
2013-03-15 09:00:36 10     34.480  
                    65    

                           PRICE  
TIMESTAMP           HSEC                            
2013-03-15 09:00:29  0     34.480 
2013-03-15 09:00:30  0     34.470  
                     1     34.485  
2013-03-15 09:00:31  0     34.495   
2013-03-15 09:00:35  0     34.485   
2013-03-15 09:00:36  0     34.480  
                     1    

这样'HSEC'在第一级索引中显示行的位置?

2 个答案:

答案 0 :(得分:0)

从这些数据开始:

In [119]: df
Out[119]: 
                           PRICE
TIMESTAMP           HSEC        
2013-03-15 09:00:29 1     34.480
2013-03-15 09:00:30 0     34.470
                    3     34.485
2013-03-15 09:00:31 0     34.495
2013-03-15 09:00:35 0     34.485
2013-03-15 09:00:36 10    34.480
                    65    34.480

我的方法是将第一级别的指标分组,然后使用range进行转换,以获得每组中的一系列位置。然后,构建一个元组列表以创建一个新的MultiIndex。

In [120]: positions = df.groupby(level=0).transform(lambda x: range(len(x))).values.ravel()

In [121]: new_index = [(timestamp, position) for ((timestamp, _), position) in 
     ...:                        zip(df.index, positions)]

In [122]: df.index = pd.MultiIndex.from_tuples(new_index)

In [123]: df
Out[123]: 
                        PRICE
2013-03-15 09:00:29 0  34.480
2013-03-15 09:00:30 0  34.470
                    1  34.485
2013-03-15 09:00:31 0  34.495
2013-03-15 09:00:35 0  34.485
2013-03-15 09:00:36 0  34.480
                    1  34.480

答案 1 :(得分:0)

chrisb的答案实际上运行正常。但是,我对许多大型数据帧进行了此操作。所以速度对我很重要。

我找到了一种看起来很丑陋的方式,但跑得快得多。

runlength = np.array(df.index.labels[0])

runlength = np.append(0,np.diff(runlength))

runlength = np.append(np.nonzero(runlength),len(df.index))
runlength = np.diff(np.append(0,runlength))

cumrunlength = np.cumsum(runlength)
cumrunlength = np.append(0,cumrunlength)
mylabel = df.index.labels[0]
neworder = [x - cumrunlength[mylabel[x]] for x in xrange(len(mylabel))]

df.reset_index(['TIMESTAMP','HSEC'], drop=False, inplace=True)
df['newIndex'] = neworder

df.set_index(['TIMESTAMP','newIndex'],inplace=True)

首先,我检查第一级标签的位置变化。发生这些变化的索引的差异给出了每次运行的长度,即每个唯一的' TIMESTAMP'条目。然后通过从连续索引0,1,2,...,n中减去累计长度到达相应位置来确定位置。

我对python和pandas很新。所以我不知道如何进行适当的速度比较。使用简单的start_time = time.clock()和print time.clock() - start_time,' seconds',我发现chrisb的代码大约需要4到5秒,而上面的代码需要0.04秒在长度为16325的数据帧上。我的猜测是,这是由于.groupby()操作起循环作用。这是对的吗?