0

我正在尝试为下面描述的情况找到最快、最优雅的解决方案。

我有一个大的 DataFrame,其中包含一些机器状态的记录。对于这个例子,假设我们只有两台机器:onetwo(实际上我有更多,但这不重要)。每台机器都可以处于以下两种状态之一:updown

以下是如何创建示例记录:

import pandas as pd

df = pd.DataFrame({'time' : range(8),
'machine' : ["one","one","two","two","one","two","two","one"],
'status' : ["up","down","up","down","up","up","down","down"]})

以及它的样子:

time    machine status
0       one     up
1       one     down
2       two     up
3       two     down
4       one     up
5       two     up
6       two     down
7       one     down

记录是严格排序的(实际上是按时间戳)。

现在,我想要实现的是找到两台机器都处于高状态(up)的情况,并且最好返回 DataFrame 的一个子集,以显示这种情况。在上面的示例中,时间5和之间的子集6对我来说很有趣,因为当时onetwo机器都处于up状态。

蛮力解决方案可能是遍历数据框并将所有机器的状态存储在一个列表中,在每次迭代期间检查我们是否有两个处于一个状态up,但也许有更优雅的解决方案?

所有建议都非常受欢迎。

4

1 回答 1

3

要开始,像这样的东西怎么样

df2 = df.pivot(index="time", columns="machine", values="status")
df2 = df2.fillna(method='ffill')
both_up = df2[(df2 == "up").all(axis=1)]

产生

>>> both_up
machine one two
time           
5        up  up

给出你的例子。


首先,构建初始DataFrame

>>> df = pd.DataFrame({'time' : range(8),
'machine' : ["one","one","two","two","one","two","two","one"],
'status' : ["up","down","up","down","up","up","down","down"]})
>>> df
  machine status  time
0     one     up     0
1     one   down     1
2     two     up     2
3     two   down     3
4     one     up     4
5     two     up     5
6     two   down     6
7     one   down     7

然后转:

>>> df2 = df.pivot(index="time", columns="machine", values="status")
>>> df2
machine   one   two
time               
0          up   NaN
1        down   NaN
2         NaN    up
3         NaN  down
4          up   NaN
5         NaN    up
6         NaN  down
7        down   NaN

在时间 2 之前,我们对机器 2 的状态一无所知——除非我们假设只记录了转换而不记录状态,所以它之前一定是关闭的——但我们可以猜测其他缺失的状态,假设所有相关变化被捕获。IOW,我们可以向前填充:

>>> df2 = df2.fillna(method='ffill')
>>> df2
machine   one   two
time               
0          up   NaN
1        down   NaN
2        down    up
3        down  down
4          up  down
5          up    up
6          up  down
7        down  down

然后我们可以寻找他们都在的地方:

>>> (df2 == "up").all(axis=1)
time
0       False
1       False
2       False
3       False
4       False
5        True
6       False
7       False
dtype: bool
>>> both_up = df2[(df2 == "up").all(axis=1)]
>>> both_up
machine one two
time           
5        up  up

只需多一点努力,您就可以从中获得[5,6)一些持续时间的测量结果,但希望以上内容可以帮助您入门。

于 2013-10-08T17:59:54.567 回答