Python 查找相等值组的索引
我有一个包含-1,0,1的一维数组Python 查找相等值组的索引,python,pandas,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 有没有办法做到这一点,或者我必须在掩码上使用一个循环? 这是我的尝试 Change =pd.DataFram
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
有没有办法做到这一点,或者我必须在掩码上使用一个循环?
这是我的尝试
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()]
Change=pd.DataFrame(列=['Start'、'End'、'Value']
i=-1
当i时,您可以在Mask
数组上的Series
中使用diff
方法(将其转换为Series
):
变化应该是这样的:
end start value
0 2 0 0
1 4 3 -1
2 6 5 0
3 8 7 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
解决方案:
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
结果:
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
更新:未来解决方案警告:不推荐使用带重命名的dict,并将在未来版本中删除
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
所以问题是你是否可以在没有for循环的情况下完成它?是的,基本上我想检查for循环中的下一个值等等。。。但我认为有一种类似于Python的方法来实现soI,我知道列表理解看起来很酷,但我认为for
循环没有什么错。另一件你可以看的事情是groupby
()我在编辑的问题中用2个while循环发布了我的解决方案。。。我认为这不是最优雅的。。。你能看一下吗?嗨@Abdou,如果掩码是pd.Series(np.array([0,0,0,-1,-1,0,0,1]),这个方法不起作用。嗨@MaxU,这给了我一个警告…C:\ProgramData\Anaconda2\lib\site packages\pandas\core\groupby.py:3961:FutureWarning:不推荐使用带重命名的dict,并将在将来的版本中删除(DataFrameGroupBy,self).aggregate(arg,*args,**kwargs)@gabboshow,是的,API在Pandas 0.20.0中已更改,因此在.agg()
中使用dict of dicts将被弃用。我已更新了答案