列增量计数器,并根据其他列重置

  • 本文关键字:其他 计数器 python pandas
  • 更新时间 :
  • 英文 :


我正在尝试创建一个列,当它按一列和基于另一列向下行组时增量计数。

另外,如果其中一个状态为空(如在空字符串中),它将被忽略,并从前一个状态中重复该空白的计数。

我有这个数据

car  status  
0    audi   False      
1    audi   False      
2    audi   False      
3    audi    True      
4     bmw   False     
5     bmw   ''      
6     bmw   False      
7     bmw    True      
8     bmw   False      
9   lexus    True      
10  lexus    True      
11  lexus    True

我想添加一列,计算有多少连续的False处于状态,因为它计数每个car,并在有True时重置,如果有另一个False或另一个car,则重新开始

car  status  counter
0    audi   False  1
1    audi   False  2   
2    audi   False  3   
3    audi    True  0   
4     bmw   False  1   
5     bmw   ''     1 
5     bmw   False  2    
6     bmw    True  0    
7     bmw   False  1         
9   lexus    True  0
10  lexus    True  0   
11  lexus   False  1

我正在尝试这个,但它增加了car

import pandas as pd
data = [['audi', False],
['audi', False],
['audi', False],
['audi', True],
['bmw', False],
['bmw', False],
['bmw', False],
['bmw', True],
['bmw', False],
['lexus', True],
['lexus', True],
['lexus', False]]
df = pd.DataFrame(data=data, columns=['car', 'status'])
df['count'] = df.groupby('car')['status'].transform(lambda x: x.ne(x.shift()).cumsum())
print(df)

您可以使用GroupBy.cumcount对连续值进行分组,最后通过Series.mask设置0status=True值:

s = df['status'].eq(True)
df['count'] = (df.groupby(['car', s.ne(s.shift()).cumsum()])
.cumcount()
.add(1)
.mask(df['status'], 0))
print(df)
car  status  count
0    audi   False      1
1    audi   False      2
2    audi   False      3
3    audi    True      0
4     bmw   False      1
5     bmw   False      2
6     bmw   False      3
7     bmw    True      0
8     bmw   False      1
9   lexus    True      0
10  lexus    True      0
11  lexus   False      1

另一种解决方案,仅用于布尔列:

s = df['status'].eq(True)
df['count'] = (df.groupby(['car', (~s & s.shift(fill_value=False)).cumsum()])
.cumcount()
.add(1)
.mask(df['status'], 0))

编辑:

data = [['audi', False],        
['audi', False],         
['bmw', False],        
['bmw', False],        
['bmw', ''],         
['bmw', ''],         
['bmw', False],         
['bmw', True],         
['bmw', False],         
['lexus', True],         
['lexus', True],         
['lexus', False]]
df = pd.DataFrame(data=data, columns=['car', 'status'])

m = df['status'].isin([True, False])
df1 = df[m].copy()
df.loc[m, 'count'] = (df1.groupby(['car', df1['status'].ne(df1['status'].shift()).cumsum()])
.cumcount())
df['count'] = df.groupby('car')['count'].bfill().fillna(0).astype('int')
print(df)
car status  count
0    audi  False      0
1    audi  False      1
2     bmw  False      0
3     bmw  False      1
4     bmw             2
5     bmw             2
6     bmw  False      2
7     bmw   True      0
8     bmw  False      0
9   lexus   True      0
10  lexus   True      1
11  lexus  False      0

最新更新