Python 第一次达到某个数字时递增计数器
这可能是一个非常愚蠢的问题。但是,我还是会继续问。仅当第一次达到某个特定值时,如何增加计数器 例如,如果我将下面的步骤作为df的一列,并希望添加一个名为“counter”的计数器列,该计数器列在“step”列第一次具有值6时递增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
,一种不需要迭代的可能方法是
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)