Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 加速循环计数器_Python_Pandas_Loops_For Loop - Fatal编程技术网

Python 加速循环计数器

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

所以我现在正在一行一行地更新计数器,我认为这不是最快的方法

下面是我使用的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    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怎么样?