Python 熊猫如何在差异在一定距离内的序列中找到连续值
我有一个由Python 熊猫如何在差异在一定距离内的序列中找到连续值,python,python-3.x,pandas,numpy,Python,Python 3.x,Pandas,Numpy,我有一个由ints组成的pandas系列 a = np.array([1,2,3,5,7,10,13,16,20]) pd.Series(a) 0 1 1 2 2 3 3 5 4 7 5 10 6 13 7 16 8 20 现在我想把这个系列分成几个组,每个组中,两个相邻值之间的差异是,这里有一种方法- np.split(a,np.flatnonzero(np.diff(a)>d)+1) 作为输出列表列表的函数- def splitme(a,d) : re
int
s组成的pandas
系列
a = np.array([1,2,3,5,7,10,13,16,20])
pd.Series(a)
0 1
1 2
2 3
3 5
4 7
5 10
6 13
7 16
8 20
现在我想把这个系列分成几个组,每个组中,两个相邻值之间的差异是,这里有一种方法-
np.split(a,np.flatnonzero(np.diff(a)>d)+1)
作为输出列表列表的函数-
def splitme(a,d) :
return list(map(list,np.split(a,np.flatnonzero(np.diff(a)>d)+1)))
对于性能,我建议使用zip
开始,停止索引,然后切片,从而避免可能成为瓶颈的np.split
-
def splitme_zip(a,d) :
m = np.concatenate(([True],a[1:] > a[:-1] + d,[True]))
idx = np.flatnonzero(m)
l = a.tolist()
return [l[i:j] for i,j in zip(idx[:-1],idx[1:])]
如果需要将输出作为数组列表,请使用.tolist
/映射(list,)
跳过列表转换
样本运行-
In [122]: a = np.array([1,2,3,5,7,10,13,16,20])
In [123]: splitme(a,1)
Out[123]: [[1, 2, 3], [5], [7], [10], [13], [16], [20]]
In [124]: splitme(a,2)
Out[124]: [[1, 2, 3, 5, 7], [10], [13], [16], [20]]
In [125]: splitme(a,3)
Out[125]: [[1, 2, 3, 5, 7, 10, 13, 16], [20]]
运行时测试-
In [180]: a = np.sort(np.random.randint(1,10000*2,(10000)))
In [181]: s = pd.Series(a)
In [182]: d = 3
In [183]: %timeit pandas_way(s,d) #@cᴏʟᴅsᴘᴇᴇᴅ's soln
10 loops, best of 3: 55.1 ms per loop
In [184]: %timeit np.split(a,np.flatnonzero(np.diff(a)>d)+1)
...: %timeit splitme(a,d)
...: %timeit splitme_zip(a,d)
1000 loops, best of 3: 1.47 ms per loop
100 loops, best of 3: 2.87 ms per loop
1000 loops, best of 3: 516 µs per loop
In [185]: a
Out[185]: array([ 2, 2, 2, ..., 19992, 19996, 19999])
这是使用groupby
的pandas
方式
n = 1
s
0 1
1 2
2 3
3 5
4 7
5 10
6 13
7 16
8 20
dtype: int64
m = ~s.diff().fillna(0).le(n)
v = s.groupby(m.cumsum()).apply(lambda x: x.tolist()).tolist()
v
[[1, 2, 3], [5], [7], [10], [13], [16], [20]]
被低估的评论!这对我帮助很大!
In [122]: a = np.array([1,2,3,5,7,10,13,16,20])
In [123]: splitme(a,1)
Out[123]: [[1, 2, 3], [5], [7], [10], [13], [16], [20]]
In [124]: splitme(a,2)
Out[124]: [[1, 2, 3, 5, 7], [10], [13], [16], [20]]
In [125]: splitme(a,3)
Out[125]: [[1, 2, 3, 5, 7, 10, 13, 16], [20]]
In [180]: a = np.sort(np.random.randint(1,10000*2,(10000)))
In [181]: s = pd.Series(a)
In [182]: d = 3
In [183]: %timeit pandas_way(s,d) #@cᴏʟᴅsᴘᴇᴇᴅ's soln
10 loops, best of 3: 55.1 ms per loop
In [184]: %timeit np.split(a,np.flatnonzero(np.diff(a)>d)+1)
...: %timeit splitme(a,d)
...: %timeit splitme_zip(a,d)
1000 loops, best of 3: 1.47 ms per loop
100 loops, best of 3: 2.87 ms per loop
1000 loops, best of 3: 516 µs per loop
In [185]: a
Out[185]: array([ 2, 2, 2, ..., 19992, 19996, 19999])
n = 1
s
0 1
1 2
2 3
3 5
4 7
5 10
6 13
7 16
8 20
dtype: int64
m = ~s.diff().fillna(0).le(n)
v = s.groupby(m.cumsum()).apply(lambda x: x.tolist()).tolist()
v
[[1, 2, 3], [5], [7], [10], [13], [16], [20]]