我有一个带有 True/False 值的 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()和cumsum()的各种组合,但没有成功。
有什么提示吗?
啤酒
最佳答案
您可以使用比较 shift
按连续值创建组编辑值和 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
另一种解决方案是分别计算 True
和 False
,然后对输出求和:
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 loop
关于python - 如何计算 Pandas 系列中重复出现的相同值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48127273/