如何计算 Pandas 系列中重复出现的相同值

How to count recurring identical values in a Pandas Series

我有一个具有 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() 的各种组合,但没有成功。

有什么提示吗?

麦酒

您可以使用比较 shifted values and cumsum and use it for 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 loop