Python 加速循环计数器
所以我现在正在一行一行地更新计数器,我认为这不是最快的方法 下面是我使用的df的简化版本,我有两个计数器C1计算每个“S”类别日,C2计算每次从“N”切换到“S”,但不是从“B”到“S”,除非是从“N”到“B”再到“S” 这是通过for循环和if语句完成的,但是对于170万行来说速度非常慢。 我已经做了相当多的搜索,似乎找不到更“熊猫/裸体”的方法 任何正确方向的想法或建议都将不胜感激Python 加速循环计数器,python,pandas,loops,for-loop,Python,Pandas,Loops,For Loop,所以我现在正在一行一行地更新计数器,我认为这不是最快的方法 下面是我使用的df的简化版本,我有两个计数器C1计算每个“S”类别日,C2计算每次从“N”切换到“S”,但不是从“B”到“S”,除非是从“N”到“B”再到“S” 这是通过for循环和if语句完成的,但是对于170万行来说速度非常慢。 我已经做了相当多的搜索,似乎找不到更“熊猫/裸体”的方法 任何正确方向的想法或建议都将不胜感激 Date Category C1 C2 1/1/2015 N 0 0 1/2/2015
Date Category C1 C2
1/1/2015 N 0 0
1/2/2015 N 0 0
1/5/2015 S 1 1
1/5/2015 S 2 1
1/6/2015 S 3 1
1/6/2015 S 4 1
1/7/2015 N 4 1
1/7/2015 N 4 1
1/12/2015 N 4 1
1/12/2015 N 4 1
1/13/2015 N 4 1
1/13/2015 S 5 2
1/15/2015 S 6 2
1/15/2015 B 7 2
1/16/2015 S 8 2
1/16/2015 S 9 2
1/16/2015 N 8 2
1/21/2015 N 8 2
1/21/2015 S 9 3
1/22/2015 S 10 3
通常,您希望使用
.cumsum()
累积值,并在检查上一个或下一个值时使用.shift()
。知道True
在数学表达式中等同于1
,可以节省我们一点时间
对于给定的示例值,以下各项适用:
df['C1'] = (df['Category'] == 'S').cumsum()
df['C2'] = ((df['Category'] == 'S') & (df['Category'].shift(1) == 'N')).cumsum()
然而,与
不是从“B”到“S”,除非是从“N”到“B”到“S”
使后者更复杂一些。但是,通过稍微复杂一点的设置,这应该是可能的:
df['C2'] = (((df['Category'] == 'S') & (df['Category'].shift(1) == 'N')) |
((df['Category'] == 'S') & (df['Category'].shift(1) == 'B') & (df['Category'].shift(2) == 'N'))).cumsum()
这假设您要计算的“B到S”行仅为第n-1行为n、第n行为B、第n+1行为S的行。所有其他实例将不包括在内。通常,您要使用
.cumsum()
累积值,并在检查上一个或下一个值时使用.shift()
。知道True
在数学表达式中等同于1
,可以节省我们一点时间
对于给定的示例值,以下各项适用:
df['C1'] = (df['Category'] == 'S').cumsum()
df['C2'] = ((df['Category'] == 'S') & (df['Category'].shift(1) == 'N')).cumsum()
然而,与
不是从“B”到“S”,除非是从“N”到“B”到“S”
使后者更复杂一些。但是,通过稍微复杂一点的设置,这应该是可能的:
df['C2'] = (((df['Category'] == 'S') & (df['Category'].shift(1) == 'N')) |
((df['Category'] == 'S') & (df['Category'].shift(1) == 'B') & (df['Category'].shift(2) == 'N'))).cumsum()
这假设您要计算的“B到S”行仅为第n-1行为n、第n行为B、第n+1行为S的行。所有其他实例将不包括在内。您可以仅使用一个循环来处理它。循环的主要焦点是计算S,比如计数器1。在for循环中,检查前一个是否为N,如果是,则添加到计数器2。否则,如果前一个是B,前一个是N,则添加到计数器2 例如,如果您有该类别的列表,您可以:
C1, C2 = 0, 0
for i in range(len(category)):
if category[i] == 'S':
C1 += 1
if category[max(0, i-1)] =='N':
C2 += 1
elif (category[max(0, i-1)]=='B') and (category[max(0, i-2)]=='N'):
C2 += 1
这样,就可以最小化for循环的数量。希望能有所帮助。您只需一个循环即可解决此问题。循环的主要焦点是计算S,比如计数器1。在for循环中,检查前一个是否为N,如果是,则添加到计数器2。否则,如果前一个是B,前一个是N,则添加到计数器2 例如,如果您有该类别的列表,您可以:
C1, C2 = 0, 0
for i in range(len(category)):
if category[i] == 'S':
C1 += 1
if category[max(0, i-1)] =='N':
C2 += 1
elif (category[max(0, i-1)]=='B') and (category[max(0, i-2)]=='N'):
C2 += 1
这样,就可以最小化for循环的数量。希望能有所帮助。最小化for循环的数量不会减少所需的时间-pandas的矢量化函数应该非常快最小化for循环的数量不会减少所需的时间-pandas的矢量化函数应该非常快谢谢这正是我想要的。然而,对于for循环,如果类别的第一行是“S”,我可以将计数器的第一行设置为1。使用矢量化方法有没有简单的方法来解决这个问题?i、 e从'N'@ar1847转换过来的不是这列的
'C2'
?我会的。如果那天的类别是“S”,我希望C2的第一行是1。我是用if-df['Category'].iloc[0]='S':df['C2'].iloc[0]=1如果df['Category'].iloc[0]='S':df['C2']+=1,这正是我想要的。然而,对于for循环,如果类别的第一行是“S”,我可以将计数器的第一行设置为1。使用矢量化方法有没有简单的方法来解决这个问题?i、 e从'N'@ar1847转换过来的不是这列的'C2'
?我会的。如果那天的类别是“S”,我希望C2的第一行是1。我是用if-df['Category'].iloc[0]='S':df['C2'].iloc[0]=1如果df['Category'].iloc[0]='S':df['C2']+=1怎么样?