因此,我目前正在大熊猫df中逐行更新计数器,我认为这不是最快的处理方式。
下面是我正在使用的df的简化版本,我有两个计数器C1计算每个“ S”类别的日期,C2计数每次从“ N”切换到“ S”而不是从“ B”转换为“ S”除非是从“ N”到“ B”再到“ S”的“ S”。
这是通过for循环和if语句完成的,但是在170万行中速度相当慢。 我已经做了相当多的搜索,而且似乎找不到更多的“ pandas / numpy”方法。
任何朝着正确方向的想法或指针将不胜感激。
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
答案 0 :(得分:2)
通常,您要使用.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的行。将不包括所有其他实例。
答案 1 :(得分:0)
您只能通过一个循环来解决它。循环的主要焦点是对S进行计数,例如counter1。在for循环中,检查前一个是否为N,如果是,则将其添加到counter2。否则,如果前一个为B,而前一个为N,则添加到counter2。
例如,如果您具有类别列表,则可以:
iValueMono
这样,您可以最小化for循环的数量。希望对您有所帮助。