在pandas中有条件重置的cumcount
我想创建一个累计计数的列,这个列会计算一个布尔变量(也就是只有真和假两种状态)的出现次数,但当遇到布尔变量为零的时候,它会重置为零。我想要的是一个有条件的累计计数。
我已经发布了我的代码(它是有效的),这是我对这个问题的初步尝试。不过,我想看看有没有人能提供更高效的解决方案,因为我用的循环在处理大数据框时可能会比较慢。
def counter(series_converted_to_a_list):
counter = 0
counter_list = []
# loop through the list and count
for i in range(len(series_converted_to_a_list)):
if series_converted_to_a_list[i] > 0:
counter += 1
else:
counter = 0
counter_list.append(counter)
return counter_list
# Sample dataframe
df = pd.DataFrame({'bool': [1,0,1,1,1,1,1,0,1,1,1,0,0,1,1,1]})
# convert the boolean column to a list
bool_series_converted_to_a_list = list(df['bool'])
# use the function
counter_list = counter(bool_series_converted_to_a_list)
# convert the list into a column in the sample dataframe
df['counter_list'] = counter_list
df
2 个回答
-1
我创建了一个和你输入的差不多的表格(df),然后做了以下操作:
import pandas as pd
Data = {'booleanvar': ['1','0','1','0','1','1','1']}
df = pd.DataFrame(Data)
df
for idx, entry in df.iterrows():
if idx == 0:
if entry['booleanvar'] == '0':
df.loc[idx , 'result'] = '0'
if entry['booleanvar'] == '1':
df.loc[idx , 'result'] = '1'
if idx > 0:
if entry['booleanvar'] == '0':
df.loc[idx , 'result'] = '0'
if entry['booleanvar'] == '1':
df.loc[idx , 'result'] = int(df.loc[idx-1 , 'result']) + 1
df
输出结果:
booleanvar result
0 1 1
1 0 0
2 1 1
3 0 0
4 1 1
5 1 2
6 1 3
2
你可以在把0隐藏起来之后,使用 groupby.cumcount
,并为所有以0开头的组设置一个自定义的分组,最后再用 reindex
恢复这些0:
df = pd.DataFrame({'bool': [1,0,1,1,1,1,1,0,1,1,1,0,0,1,1,1]})
m = df['bool'].eq(1)
df['cumcount'] = (m[m].groupby((~m).cumsum()).cumcount().add(1)
.reindex(df.index, fill_value=0)
)
或者,可能更简单的方法是使用 cumsum
,这样可以确保每个组的第一个1总是从1开始:
m = df['bool'].eq(1)
df['cumcount'] = m.groupby((~m).cumsum()).cumsum()
输出结果:
bool cumcount
0 1 1
1 0 0
2 1 1
3 1 2
4 1 3
5 1 4
6 1 5
7 0 0
8 1 1
9 1 2
10 1 3
11 0 0
12 0 0
13 1 1
14 1 2
15 1 3