找到相等值组的索引python

时间:2017-03-06 15:59:49

标签: python pandas

我有一个包含-1,0,1

的一维数组
Mask
Out[6]: array([0, 0, 0, -1, -1, 0, 0, 1, 1])

我想找到相等值组的开始和结束索引。 这可以存储在数据帧中,其中第一列是起始索引,第二列是结束索引,而tirdh列是重复的值。

start end value
0,    2,  0
3,    4,  -1
5,    6,  0
7,    8,  1

有没有办法做到这一点,或者我必须在Mask上使用循环? 特此我的尝试

Change =pd.DataFrame(columns=['Start','End','Value'])

i=-1
while i <len(Mask)-1:
    i = i + 1
    start = i
    end = i
    value = Mask[start]
    if i <len(Mask)-1:
       while Mask[i]==Mask[i+1]:
          i = i +1
          end = i
          if i >=len(Mask)-1:
              end = i + 1 
              break

    detected = []
    detected .append([start,end,value])
    detected = np.array(detected )
    detected = pd.DataFrame(detected , columns=['Start','End','Value'])    
    Change = pd.concat([Change , detected ], ignore_index=True)[Change .columns.tolist()]

2 个答案:

答案 0 :(得分:2)

您可以在diff数组Series上使用Mask方法(将其转换为Series后):

import numpy as np
import pandas as pd


Mask = np.array([0, 0, 0, -1, -1, 0, 0, 1, 1])
Mask = pd.Series(Mask)
starts = Mask[~Mask.diff().eq(0)].index.values
ends = Mask[Mask.diff().eq(0)].index[1:].values
vals = Mask[~Mask.diff().eq(0)].values

Change = pd.DataFrame({'start':starts, 'end':ends, 'value':vals})

改变应该是这样的:

   end  start  value
0    2      0      0
1    4      3     -1
2    6      5      0
3    8      7      1

我希望这证明有用。

答案 1 :(得分:1)

数据:

In [178]: s = pd.Series([0, 0, 0, -1, -1, 0, 0, 1, 1])

In [179]: s
Out[179]:
0    0
1    0
2    0
3   -1
4   -1
5    0
6    0
7    1
8    1
dtype: int64

<强>解决方案:

In [180]: r = (s.reset_index(name='val')
     ...:       .groupby(s.diff().ne(0).cumsum())
     ...:       .agg({'val':{'value':'first'}, 'index':{'start':'min','end':'max'}})
     ...: )
     ...:

In [182]: r.columns = r.columns.droplevel(0)

<强>结果:

In [183]: r
Out[183]:
   value  start  end
1      0      0    2
2     -1      3    4
3      0      5    6
4      1      7    8

更新: FutureWarning: using a dict with renaming is deprecated and will be removed in a future version

的解决方法
In [47]: r = s.reset_index(name='val').groupby(s.diff().ne(0).cumsum()).agg({'val':'first', 'index':['min','max']})

In [48]: r.columns = r.columns.droplevel(0)

In [49]: r = r.rename(columns={'first':'value','min':'start','max':'end'})

In [50]: r
Out[50]:
   start  end  value
1      0    2      0
2      3    4     -1
3      5    6      0
4      7    8      1