Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/323.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_Dataframe - Fatal编程技术网

Python 使用熊猫过滤器计算值之间的差异

Python 使用熊猫过滤器计算值之间的差异,python,pandas,dataframe,Python,Pandas,Dataframe,我有一个数据框,每行包含关于事件的信息,以及事件是否成功。我想计算非成功事件之间的差值,我知道如何计算字段之间的差值,但在使用过滤器时不知道 我的数据帧具有以下结构: Timestamp Status 0 2012-01-01 OK 1 2012-01-02 OK 2 2012-01-03 FAIL 3 2012-01-05 OK 4 2012-01-06 OK 5 201

我有一个数据框,每行包含关于事件的信息,以及事件是否成功。我想计算非成功事件之间的差值,我知道如何计算字段之间的差值,但在使用过滤器时不知道

我的数据帧具有以下结构:

      Timestamp     Status          
   0 2012-01-01     OK 
   1 2012-01-02     OK 
   2 2012-01-03     FAIL
   3 2012-01-05     OK 
   4 2012-01-06     OK 
   5 2012-01-07     FAIL
我想要的是计算每一行直到下一次失败的时间,因此如下所示:

      Timestamp     Status     Days_until_next_fail              
   0 2012-01-01     OK         2
   1 2012-01-02     OK         1
   2 2012-01-03     FAIL       0
   3 2012-01-05     OK         2
   4 2012-01-06     OK         1
   5 2012-01-07     FAIL       0
我试过这个:

df['days_until_next_failure'] = df.Timestamp - df[(df.Status == '1')].Timestamp(+1)

但这会返回NaT,我在文档中找不到任何应用过滤和使用shift的内容。一种选择是从末尾开始迭代数据帧,但这似乎有点低效。

如果列
时间戳
已排序并包含每个月的所有天,则解决方案为:

您可以尝试先按查找数据组,然后按此
Serie
和聚合。您可以通过
0
获得
NaN
,并通过以下方式将输出列转换为整数:

更一般的解决方案(必须对所有日期进行排序):

如果需要将列从
timedelta
转换为
int

df['fail_days'] = df.groupby((df.Status == 'FAIL').astype(int).cumsum())
                    .apply(lambda x: ((x.iloc[0][0] - x.Timestamp) / np.timedelta64(1, 'D'))
                                        .astype(int))

                    .reset_index(level=0, drop=True)

print df.sort_index()
   Timestamp Status  fail_days
0 2011-12-28     OK          6
1 2012-01-02     OK          1
2 2012-01-03   FAIL          0
3 2012-01-05     OK          2
4 2012-01-06     OK          1
5 2012-01-07   FAIL          0

以下给出了上次失败后的天数,而不是下一次失败前的天数:

is_fail = (df.Status != 'OK')
cumulative_fails = is_fail.cumsum()
fail_idx, = is_fail.nonzero()
days_since_last_fail = arange(len(is_fail))
days_since_last_fail[fail_idx[0]:] -= fail_idx[cumulative_fails[fail_idx[0]:]-1]

如果您想要正确的版本,那么您可以自行调整,或者可能只是在开始和结束时反转原始数组。

这是cumsum的工作。cumsum…尽管需要几行代码才能得到您想要的。(
cumsum
将告诉您数据中某一点上有多少个1。)您可以不使用
groupby
,只需使用“global”
cumsum
的输出将其索引到df['Timestamp'],就可以做到这一点。对不起,我不明白。在这种情况下,我必须提供我自己的答案!(我猜部分是因为我解释得不好)@chrisp-是否可能连续两次
失败
值?是的,这是可能的。因为我需要两种解决方案:失败次数和失败间隔时间两种解决方案都能完美工作。我实现了上面的代码,它工作得非常好。太糟糕了,我不能接受两个答案。是的,我要用python试试并修复它。@jezrael-我复制粘贴到快速,现在就试试它返回
[0 1 0 1 2 0]
超级,我想你明白了。非常好的工作非常完美。我颠倒了数据帧,以获得未来的日子,这是完美的工作。当某些天没有行,或者有时一天两个时间戳时,您是否也有建议?
df['fail_days'] = df.groupby((df.Status == 'FAIL').astype(int).cumsum())
                    .apply(lambda x: ((x.iloc[0][0] - x.Timestamp) / np.timedelta64(1, 'D'))
                                        .astype(int))

                    .reset_index(level=0, drop=True)

print df.sort_index()
   Timestamp Status  fail_days
0 2011-12-28     OK          6
1 2012-01-02     OK          1
2 2012-01-03   FAIL          0
3 2012-01-05     OK          2
4 2012-01-06     OK          1
5 2012-01-07   FAIL          0
is_fail = (df.Status != 'OK')
cumulative_fails = is_fail.cumsum()
fail_idx, = is_fail.nonzero()
days_since_last_fail = arange(len(is_fail))
days_since_last_fail[fail_idx[0]:] -= fail_idx[cumulative_fails[fail_idx[0]:]-1]