如何计算熊猫中最长的不间断序列

Daw*_*wei 5 python pandas

让我们说我pd.Series喜欢下面的内容

s = pd.Series([False, True, False,True,True,True,False, False])    

0    False
1     True
2    False
3     True
4     True
5     True
6    False
7    False
dtype: bool
Run Code Online (Sandbox Code Playgroud)

我想知道最长的True序列有多长,在这个例子中,它是3.

我以一种愚蠢的方式尝试过它.

s_list = s.tolist()
count = 0
max_count = 0
for item in s_list:
    if item:
        count +=1
    else:
        if count>max_count:
            max_count = count
        count = 0
print(max_count)
Run Code Online (Sandbox Code Playgroud)

它会打印3,但最重要的SeriesTrue,它会打印出来0

piR*_*red 10

选项1
使用系列本身来掩盖否定的累积和.然后用value_counts

(~s).cumsum()[s].value_counts().max()

3
Run Code Online (Sandbox Code Playgroud)

说明

  1. (~s).cumsum()是生成不同True/ False组的非常标准的方法

    0    1
    1    1
    2    2
    3    2
    4    2
    5    2
    6    3
    7    4
    dtype: int64
    
    Run Code Online (Sandbox Code Playgroud)
  2. 但你可以看到我们关心的群体由2s 代表,其中有四个.那是因为该组是由第一个发起的False(变为Truewith (~s)).因此,我们使用我们开始使用的布尔掩码来掩盖此累积和.

    (~s).cumsum()[s]
    
    1    1
    3    2
    4    2
    5    2
    dtype: int64
    
    Run Code Online (Sandbox Code Playgroud)
  3. 现在我们看到三个2弹出,我们只需要使用一个方法来提取它们.我用过value_countsmax.


选项2
使用factorizebincount

a = s.values
b = pd.factorize((~a).cumsum())[0]
np.bincount(b[a]).max()

3
Run Code Online (Sandbox Code Playgroud)

解释
这与选项1的解释类似.主要区别在于我如何找到最大值.我pd.factorize用来将值标记为整数,范围从0到唯一值的总数.鉴于我们的实际价值,(~a).cumsum()我们并不严格需要这部分.我使用它是因为它是一个可用于任意组名的通用工具.

pd.factorize我使用这些整数值后np.bincount,累积使用每个整数的总次数.然后取最大值.


备选案文3
如备选案文2的解释所述,这也有效:

a = s.values
np.bincount((~a).cumsum()[a]).max()

3
Run Code Online (Sandbox Code Playgroud)

  • @piRSquared,我如何知道最长的 true 序列出现在哪里? (3认同)

WeN*_*Ben 5

我认为这可以工作

pd.Series(s.index[~s].values).diff().max()-1
Out[57]: 3.0
Run Code Online (Sandbox Code Playgroud)

同样在熊猫之外,我们可以回到 python groupby

from itertools import groupby
max([len(list(group)) for key, group in groupby(s.tolist())])
Out[73]: 3
Run Code Online (Sandbox Code Playgroud)

更新 :

from itertools import compress
max(list(compress([len(list(group)) for key, group in groupby(s.tolist())],[key for key, group in groupby(s.tolist())])))
Out[84]: 3
Run Code Online (Sandbox Code Playgroud)