在Pandas中使用最后计算值进行顺序计算

-1 投票
1 回答
580 浏览
提问于 2025-04-29 20:07

有没有人能建议一种方法,让我可以按顺序应用一个函数,这样不仅能使用正在计算的列的最后计算值,还能使用其他列当前和过去的值,来处理一个pandas数据框。

为了说明我的使用场景,假设我有一个数据框,其中有“开始”和“结束”标记,用于表示一个事件的发生,我需要在一个叫“事件”的新列中标记事件的发生,用“1”表示。以下是各列的描述:

  • 开始:当条件满足时,这列标记为1,表示事件开始。如果这一列有1,说明要么是事件开始,要么是已经存在的事件在继续,即使“结束”列标记为2。
  • 结束:当条件满足时,这列标记为2,表示事件结束,前提是“开始”列为0。如果“开始”列为1,那么这些值对正在进行的事件没有影响。
  • 事件:这一列需要计算,标记为1的行表示事件正在进行。

这个例子的逻辑是,我用1开始事件,并在1和2重叠时或在接下来的两个值结束时结束事件。

    Start   End   Event
1   0       0     0
2   1       2     1
3   1       2     1
4   0       0     0
5   0       0     0
6   0       0     0
7   1       0     1
8   0       2     1
9   0       2     0
10  0       0     0

我明白,如果我能找到一种方法,按顺序使用其他列的当前行值来实现一个函数,我就可以轻松地使用这些列的过去值,方法是用.shift(...)。到目前为止,我找到了一种在同一列上进行顺序计算的python实现:https://groups.google.com/forum/#!topic/pydata/0MCWhwurOWs,还有这段python代码:https://github.com/pydata/pandas/issues/4567

我从来没有使用过cython,想知道是否可以用上述方法来实现。

总的来说,我觉得pandas缺少一种简单的计算方式,让我不仅能参考其他列的值,还能参考同一列的计算值,以便对当前行进行计算。这很困难,因为pandas是基于列的,并且应用的是基于列的数组函数。

我非常希望能得到帮助。

暂无标签

1 个回答

0

好的,即使在澄清之后,你的问题还是不太清楚。你给的例子实际上违反了你自己的定义,因为第二行开始的事件从来没有结束,因为第三行和第四行都没有满足你目前所说的结束条件:(“如果开始为1,结束为2的值对正在进行的事件没有任何影响?!)”

不过,这里有一个大致的解决思路,你可以在这个基础上进行调整,剩下的部分你可以自己搞定:

  • 你需要用到的工具是 diffcumsum。你还需要做一些布尔计算。
  • diff() 会给你正的和负的变化;因为你只关心最早的正变化,所以可以比较 diff(...) == +1 的输出。
  • 在这里,我们计算两个中间向量 event_started 和 event_ended,然后将它们转换成整数,这样我们就可以进行累加和 cumsum(as.integer(event_started) - as.integer(event_ended)),这似乎正是你想要的:

.

df <- data.frame(Start=c(0,1,1,0,0,0,1,0,0,0), End=c(0,2,2,0,0,0,0,2,2,0))

event_started <- c(F, diff(df$Start)) == +1
FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
event_ended   <- c(F, diff(df$End==2) == +1) & !event_started
FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE

cumsum(as.integer(event_started) - as.integer(event_ended))
0 1 1 1 1 1 2 1 1 1

df$Event <- cumsum(as.integer(event_started) - as.integer(event_ended))

撰写回答