Python - 在200万行表格中使用计数器

5
作为一个例子,我有以下数据框:
Date                     Balance
2013-04-01 03:50:00         A
2013-04-01 04:00:00         A
2013-04-01 04:15:00         B
2013-04-01 04:15:00         B
2013-04-01 04:25:00         A
2013-04-01 04:25:00         A
2013-04-01 04:35:00         B
2013-04-01 04:40:00         B
2013-04-02 04:55:00         B
2013-04-02 04:56:00         A
2013-04-02 04:57:00         A
2013-04-03 10:30:00         A
2013-04-03 16:35:00         A
2013-04-03 20:40:00         A

我的目标是添加一列“计数器”,它基本上显示A和B的数量平衡。因此,每次出现A时,计数器列增加一个值。每次出现B时,计数器列减少一个值。如果两个A同时出现(相同的日期)在两个连续的行中,则平衡应该在这两个行上增加两个(对于连续的B或同时出现的A和B也适用相同的推理)。因此,最终数据框应如下所示:
 Date                     Balance        Counter
2013-04-01 03:50:00         A               1
2013-04-01 04:00:00         A               2
2013-04-01 04:15:00         B               0
2013-04-01 04:15:00         B               0
2013-04-01 04:25:00         A               2
2013-04-01 04:25:00         A               2
2013-04-01 04:35:00         B               1
2013-04-01 04:40:00         B               0
2013-04-02 04:55:00         B              -1
2013-04-02 04:56:00         A               0
2013-04-02 04:57:00         A               1
2013-04-03 10:30:00         A               2
2013-04-03 16:35:00         A               3
2013-04-03 20:40:00         A               4

主要问题是数据框中有超过2百万行,因此使用循环进行操作非常耗时。是否有实现矢量化方法的方式来解决这个问题?

编辑(如果连续行上的日期不同,则我能够编译有效的解决方案)。 有人可以帮我找出剩下的部分吗?

d = {'Date': ['2013-04-01 03:50:00', '2013-04-01 04:00:00','2013-04-01 
04:15:00','2013-04-01 04:15:00','2013-04-01 04:25:00',
'2013-04-01 04:25:00','2013-04-01 04:35:00','2013-04-01 04:40:00','2013-04- 
02 04:55:00','2013-04-02 04:56:00',         
'2013-04-02 04:57:00','2013-04-03 10:30:00','2013-04-03 16:35:00','2013-04- 
03 20:40:00'], 'Balance': ['A','A','B','B','A','A','B','B','B',                                                                                                
'A','A','A','A','A',]}

df = pd.DataFrame(data=d)

df['plus_minus'] = np.where(df.Balance == 'A', 1, -1)
df['Counter'] = df['plus_minus'].cumsum()

我不确定你的示例输出和描述是否匹配?为什么它不是 [2, 2, 0, 0...] 或者 [1, 2, 1, 0...] 呢? - Jon Clements
@JonClements 我认为这是因为当连续出现两个A或B时,它会立即加上2个单位,而不是连续两次增加1个单位。 - Stephen Witkowski
Miguel,你能展示一下你目前的工作进展吗? - Stephen Witkowski
1
@StephenWitkowski,我刚刚编辑了这个问题。 - Miguel Lambelho
@AmitWolfenfeld,我的草稿解决方案就是这样。但是,我不知道如何处理连续行中相同的日期。 - Miguel Lambelho
显示剩余4条评论
1个回答

6

有一种方法是按日期分组并汇总值。该值的累积和给出了该日期结束时的净值,然后我们可以按日期重新索引以将结果广播回到主框架:

df['plus_minus'] = np.where(df.Balance == 'A', 1, -1)
by_dt = df["plus_minus"].groupby(df["Date"]).sum().cumsum()
df["Counter2"] = by_dt.reindex(df.Date).values

给我
                   Date Balance  Counter  plus_minus  Counter2
0   2013-04-01 03:50:00       A        1           1         1
1   2013-04-01 04:00:00       A        2           1         2
2   2013-04-01 04:15:00       B        0          -1         0
3   2013-04-01 04:15:00       B        0          -1         0
4   2013-04-01 04:25:00       A        2           1         2
5   2013-04-01 04:25:00       A        2           1         2
6   2013-04-01 04:35:00       B        1          -1         1
7   2013-04-01 04:40:00       B        0          -1         0
8   2013-04-02 04:55:00       B       -1          -1        -1
9   2013-04-02 04:56:00       A        0           1         0
10  2013-04-02 04:57:00       A        1           1         1
11  2013-04-03 10:30:00       A        2           1         2
12  2013-04-03 16:35:00       A        3           1         3
13  2013-04-03 20:40:00       A        4           1         4

是的,这似乎是正确的方法。我没有意识到最后一个条件,在示例中没有出现。 - ALollz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接