在pandas中有条件重置的cumcount

-1 投票
2 回答
67 浏览
提问于 2025-04-13 03:09

我想创建一个累计计数的列,这个列会计算一个布尔变量(也就是只有真和假两种状态)的出现次数,但当遇到布尔变量为零的时候,它会重置为零。我想要的是一个有条件的累计计数。

我已经发布了我的代码(它是有效的),这是我对这个问题的初步尝试。不过,我想看看有没有人能提供更高效的解决方案,因为我用的循环在处理大数据框时可能会比较慢。

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

撰写回答