Python 第一次达到某个数字时递增计数器

Python 第一次达到某个数字时递增计数器,python,pandas,counter,Python,Pandas,Counter,这可能是一个非常愚蠢的问题。但是,我还是会继续问。仅当第一次达到某个特定值时,如何增加计数器 例如,如果我将下面的步骤作为df的一列,并希望添加一个名为“counter”的计数器列,该计数器列在“step”列第一次具有值6时递增 如果您的数据帧被称为df,一种不需要迭代的可能方法是 df['counter'] = 0 df.loc[1:, 'counter'] = ((df['steps'].values[1:] == 6) & (df['steps'].values[:-1] != 6

这可能是一个非常愚蠢的问题。但是,我还是会继续问。仅当第一次达到某个特定值时,如何增加计数器

例如,如果我将下面的步骤作为df的一列,并希望添加一个名为“counter”的计数器列,该计数器列在“step”列第一次具有值6时递增


如果您的数据帧被称为
df
,一种不需要迭代的可能方法是

df['counter'] = 0
df.loc[1:, 'counter'] = ((df['steps'].values[1:] == 6) & (df['steps'].values[:-1] != 6)).cumsum()

这将创建两个布尔数组,当前一行不包含6而当前行包含6时,该数组的连接为真。您可以对该数组求和以获得计数器。

这不是一个愚蠢的问题。要在
计数器
列中获得所需的输出,您可以尝试(例如)以下操作:

结果:

>> [7, 13, 18]
,这是第一个
6
发生的
步骤中的索引。现在,您可以使用
len(counter)
获得发生的总时间,或者按照您使用指定的方式复制第二列

counter_column = [0]
for idx in range(len(steps)):
    counter_column.append(counter_column[-1])
    if idx in counter:
        counter_column[-1] += 1

如果您的数据帧称为df,则

import pandas as pd

q_list = [2, 2, 2, 3, 4, 4, 5, 6, 6, 6, 6, 7, 5, 6, 6, 6, 7, 5, 6, 7, 5]
df = pd.DataFrame(q_list, columns=['step'])
counter = 0 
flag = False
for index, row in df.iterrows():
    if row ['step'] == 6 and flag == False:
         counter += 1
         flag = True
    elif row ['step'] != 6 and flag == True:
         flag = False
    df.set_value(index,'counter',counter) 
您可以在
pandas
中使用
.shift()

请注意,如果
df['step']
的值为
6
df.shift(1)['step']
的值是而不是6

输出

      step  counter
0      2        0
1      2        0
2      2        0
3      3        0
4      4        0
5      4        0
6      5        0
7      6        1
8      6        1
9      6        1
10     6        1
11     7        1
12     5        1
13     6        2
14     6        2
15     6        2
16     7        2
17     5        2
18     6        3
19     7        3
20     5        3
解释

a<如果
step
6,则code>df['step']==6
给出
boolean
值-
True

0     False
1     False
2     False
3     False
4     False
5     False
6     False
7      True
8      True
9      True
10     True
11    False
12    False
13     True
14     True
15     True
16    False
17    False
18     True
19    False
20    False
Name: step, dtype: bool
b<代码>df.shift(1)[“步骤”]=6
将数据移位1行,然后检查值是否等于6

当这两个条件都满足时,您需要递增-
。cumsum()
将处理该问题。希望有帮助

p.S-虽然这是一个好问题,但请避免粘贴图像。您可以直接将数据和格式粘贴为代码。帮助回答复制粘贴的人员使用:

df = pd.DataFrame({'step':[2, 2, 2, 3, 4, 4, 5, 6, 6, 6, 6, 7, 5, 6, 6, 6, 7, 5, 6, 7, 5]})

a = df['step'] == 6
b = (~a).shift()
b[0] = a[0]
df['counter1'] = (a & b).cumsum()

print (df)
    step  counter
0      2        0
1      2        0
2      2        0
3      3        0
4      4        0
5      4        0
6      5        0
7      6        1
8      6        1
9      6        1
10     6        1
11     7        1
12     5        1
13     6        2
14     6        2
15     6        2
16     7        2
17     5        2
18     6        3
19     7        3
20     5        3
说明

获取用于与
6
进行比较的布尔掩码:

a = df['step'] == 6
反转
系列
和:

如果第一个值是
6
,则不获取第一组,因此需要通过第一个
a
值设置第一个值:

b[0] = a[0]
位和
-
链接条件:

c = a & b
获取累计总和:

d = c.cumsum()

print (pd.concat([df['step'], a, b, c, d], axis=1, keys=('abcde')))

    a      b      c      d  e
0   2  False  False  False  0
1   2  False   True  False  0
2   2  False   True  False  0
3   3  False   True  False  0
4   4  False   True  False  0
5   4  False   True  False  0
6   5  False   True  False  0
7   6   True   True   True  1
8   6   True  False  False  1
9   6   True  False  False  1
10  6   True  False  False  1
11  7  False  False  False  1
12  5  False   True  False  1
13  6   True   True   True  2
14  6   True  False  False  2
15  6   True  False  False  2
16  7  False  False  False  2
17  5  False   True  False  2
18  6   True   True   True  3
19  7  False  False  False  3
20  5  False   True  False  3
如果性能很重要,请使用
numpy
解决方案:

a = (df['step'] == 6).values
b = np.insert((~a)[:-1], 0, a[0])
df['counter1'] = np.cumsum(a & b)

这将使计数器每次增加6。我只想在我的列第一次达到6时增加它。@nnnmmm-Jep,我忘记了
范围,我现在修复了它是的,但OP不想要最后的数字,而是在那一刻用相应的计数器值填充每一行。(或者至少这是我所理解的)我唯一喜欢的部分是,这不是一个“愚蠢的问题”。我将对我的答案进行一点扩展,我的方法可以适用于包含这一部分。你可以通过不做列表理解中的求和来轻松实现所需的输出,但是一个cumsumNope不会产生所需的输出(请参见@nnnmmm答案),您也在迭代,但根本不使用索引!没错,我加了一面旗。即使有更好的答案,现在也应该可以了。如果我的答案或其他答案有帮助,别忘了-点击复选标记(
),将其从灰显切换为填充。谢谢
c = a & b
d = c.cumsum()

print (pd.concat([df['step'], a, b, c, d], axis=1, keys=('abcde')))

    a      b      c      d  e
0   2  False  False  False  0
1   2  False   True  False  0
2   2  False   True  False  0
3   3  False   True  False  0
4   4  False   True  False  0
5   4  False   True  False  0
6   5  False   True  False  0
7   6   True   True   True  1
8   6   True  False  False  1
9   6   True  False  False  1
10  6   True  False  False  1
11  7  False  False  False  1
12  5  False   True  False  1
13  6   True   True   True  2
14  6   True  False  False  2
15  6   True  False  False  2
16  7  False  False  False  2
17  5  False   True  False  2
18  6   True   True   True  3
19  7  False  False  False  3
20  5  False   True  False  3
a = (df['step'] == 6).values
b = np.insert((~a)[:-1], 0, a[0])
df['counter1'] = np.cumsum(a & b)