pandas - 更改第二级索引的值以显示在第一级索引中的位置
我该如何将第二级索引的值从
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
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(),然后打印出time.clock() - start_time,'秒',我发现chrisb的代码大约需要4到5秒,而我上面的代码在一个长度为16325的数据框上只需要0.04秒。我猜这可能是因为.groupby()操作像循环一样工作。这样理解对吗?
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
来生成每个组内的位置数组。接着,构建一个元组的列表,以创建一个新的多重索引。
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