我有一个带有真值/假值的Pandas系列,我需要计算一个值与前一个值相同的频率。
每当值发生变化时,计数应在1处重新启动。
pd.Series([True, False, False, False, True, True, False])
0 True --> 1
1 False --> 1
2 False --> 2
3 False --> 3
4 True --> 1
5 True --> 2
6 False --> 1
dtype: bool我尝试了shift()和累计()的各种组合,但都没有成功。
有什么暗示吗?
白酒
发布于 2018-01-06 12:24:58
可以使用比较shift、ed值和cumsum的连续值创建组,并将其用于cumcount。
s = pd.Series([True, False, False, False, True, True, False])
s1 = s.groupby(s.ne(s.shift()).cumsum()).cumcount().add(1)
print (s1)
0 1
1 1
2 2
3 3
4 1
5 2
6 1
dtype: int64详细信息:
print (s.ne(s.shift()).cumsum())
0 1
1 2
2 2
3 2
4 3
5 3
6 4
dtype: int32另一种解决方案是分别计算Trues和Falses,然后求和输出:
cm1 = s.cumsum()
s1 = cm1-cm1.where(~s).ffill().fillna(0)
cm2 = (~s).cumsum()
s2 = cm2-cm2.where(s).ffill().fillna(0)
s3 = s1.add(s2).astype(int)
print (s3)
0 1
1 1
2 2
3 3
4 1
5 2
6 1
dtype: int32详细信息:
print (s1)
0 1.0
1 0.0
2 0.0
3 0.0
4 1.0
5 2.0
6 0.0
dtype: float64
print (s2)
0 0.0
1 1.0
2 2.0
3 3.0
4 0.0
5 0.0
6 1.0
dtype: float64时间
np.random.seed(2018)
N = 1000000
s = pd.Series(np.random.choice([True, False], N))
#print (s)
def jez1(s):
return s.groupby(s.ne(s.shift()).cumsum()).cumcount().add(1)
def jez2(s):
cm1 = s.cumsum()
s1 = cm1-cm1.where(~s).ffill().fillna(0)
cm2 = (~s).cumsum()
s2 = cm2-cm2.where(s).ffill().fillna(0)
return s1.add(s2).astype(int)print (jez1(s))
print (jez2(s))
In [173]: %timeit jez1(s)
1 loop, best of 3: 199 ms per loop
In [174]: %timeit jez2(s)
10 loops, best of 3: 92 ms per loophttps://stackoverflow.com/questions/48127273
复制相似问题