我正在尝试创建一个列,当它按一列和基于另一列向下行组时增量计数。
另外,如果其中一个状态为空(如在空字符串中),它将被忽略,并从前一个状态中重复该空白的计数。
我有这个数据
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
设置0
对status=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