如何基于列分组重新索引python数据帧

如何基于列分组重新索引python数据帧,python,pandas,indexing,rows,Python,Pandas,Indexing,Rows,我是python的新手。请帮忙。我有一个由数千行组成的巨大数据帧。df的示例如下所示 STATE VOLUME INDEX 1 on 10 2 on 15 3 on 10 4 off 20 5 off 30 6 on 15 7 on 20 8

我是python的新手。请帮忙。我有一个由数千行组成的巨大数据帧。df的示例如下所示

        STATE        VOLUME
INDEX           
1       on         10
2       on         15
3       on         10
4       off        20
5       off        30
6       on         15
7       on         20
8       off        10
9       off        30
10      off        10
11      on         20
12      off        25
我希望能够根据“状态”列对该数据进行索引,以便第一批“开”和“关”寄存器作为索引1,下一批“开”和“关”寄存器作为索引2等。。。如果选择索引为1的行,我希望能够选择一组数据

       ID        VOLUME
INDEX           
1       on         10
1       on         15
1       on         10
1       off        20
1       off        30
2       on         15
2       on         20
2       off        10
2       off        30
2       off        10
3       on         20
3       off        25
您可以尝试以下方法:

np相同。其中

temp=pd.Series(np.where((df.STATE.shift(-1) != df.STATE)&(df.STATE.eq('off')),1,0))
df.index=temp.shift(1,fill_value=0).cumsum().astype(int).add(1)
输出:

df
  STATE  VOLUME
1    on      10
1    on      15
1    on      10
1   off      20
1   off      30
2    on      15
2    on      20
2   off      10
2   off      30
2   off      10
3    on      20
3   off      25

说明: 使用
(df.STATE.shift(-1)!=df.STATE)&df.STATE.eq('off')
,当最后一个值变为'off'时,您将得到一个掩码:

(df.STATE.shift(-1) != df.STATE)&df.STATE.eq('off')

1     False
2     False
3     False
4     False
5      True
6     False
7     False
8     False
9     False
10     True
11    False
12     True
然后移动它以包含最后一个值,然后执行
cumsum()
,知道
True:1
False:0

((df.STATE.shift(-1) != df.STATE)&df.STATE.eq('off')).shift(fill_value=0)
1         0
2     False
3     False
4     False
5     False
6      True
7     False
8     False
9     False
10    False
11     True
12    False

((df.STATE.shift(-1) != df.STATE)&df.STATE.eq('off')).shift(fill_value=0).cumsum()
1     0
2     0
3     0
4     0
5     0
6     1
7     1
8     1
9     1
10    1
11    2
12    2
最后,将1(
+1
)添加到索引中,以获得所需的结果。

您可以使用尝试此操作,并使用

细节 其思想是找出
关闭
后跟着
打开
的位置

# (df['STATE'].eq('off').shift() & df['STATE'].eq('on')).cumsum() + 1

      eq(off).shift  eq(on)  eq(off).shift & eq(on)
INDEX
1               NaN    True                   False
2             False    True                   False
3             False    True                   False
4             False   False                   False
5              True   False                   False
6              True    True                    True
7             False    True                   False
8             False   False                   False
9              True   False                   False
10             True   False                   False
11             True    True                    True
12            False   False                   False

批次是否总是5次观察?你能澄清一下“行间距不一样”是什么意思吗?你能分享一些你已经尝试过的代码吗?@heilala这不仅仅是5个观察结果。我只取了一部分数据,因为它包含数千行,有“开”和“关”批。你有5倍索引1,5倍索引2。。。我想问的是,索引是否总是以5为一批?或者你如何确定,哪些观察结果属于同一批?冷静的第一个问题。欢迎来到;)回答得不错@Ch3steR+1。
df.index = (df['STATE'].eq('off').shift() & df['STATE'].eq('on')).cumsum() + 1
df.index.name = 'INDEX'

      STATE  VOLUME
INDEX
1        on      10
1        on      15
1        on      10
1       off      20
1       off      30
2        on      15
2        on      20
2       off      10
2       off      30
2       off      10
3        on      20
3       off      25
# (df['STATE'].eq('off').shift() & df['STATE'].eq('on')).cumsum() + 1

      eq(off).shift  eq(on)  eq(off).shift & eq(on)
INDEX
1               NaN    True                   False
2             False    True                   False
3             False    True                   False
4             False   False                   False
5              True   False                   False
6              True    True                    True
7             False    True                   False
8             False   False                   False
9              True   False                   False
10             True   False                   False
11             True    True                    True
12            False   False                   False