标记n天之内行是否符合条件

时间:2019-03-02 15:51:34

标签: python pandas

In a previous question,@ KartikeySingh,让我非常接近。但是我需要通过在5天的时间内至少有90%的流量流出(负流量)时仅标记正流入来进一步完善它。因此,在下面的示例中,不应标记索引4和5,但是应该标记索引项7、10、17和19,因为流入和流出满足这些参数。因此,我将如何仅标记彼此相差90%以内(负值)的流入和流出,并且流出发生在流入的5天之内。

stream = [2, 0, 1, 0, 3, 2, 100, 0, 0, -95, 3, 0, 2, -1, 0, 2, 93, -2, -89]
date = [
'2019-01-01', '2019-01-02', '2019-01-03', '2019-01-04', '2019-01-05',
'2019-01-06', '2019-01-07', '2019-01-08', '2019-01-09', '2019-01-10',
'2019-01-11', '2019-01-13', '2019-01-14', '2019-01-15', '2019-01-16',
'2019-01-17', '2019-01-18', '2019-01-19', '2019-01-20'
]

df = pd.DataFrame({'date': date, 'stream': stream})

def process(row):
if row['stream'] > 20*row['stream_mean']:
    return 1
else:
    return 0
df['stream_mean'] = df['stream'].rolling(5).mean()
df['stream_mean'] = df['stream_mean'].shift(periods=1)
df['flag'] = df.apply(process,axis=1)
df

上面的代码标记所有流入的流量,而不考虑流出的条件。

1 个答案:

答案 0 :(得分:1)

使用.loc可以更轻松地解决此问题,您可以使用以下代码,代码中的注释说明了逻辑:

这部分只是问题代码的副本:

import pandas as pd
import numpy as np
stream = [2, 0, 1, 0, 3, 2, 100, 0, 0, -95, 3, 0, 2, -1, 0, 2, 93, -2, -89]
date = [
'2019-01-01', '2019-01-02', '2019-01-03', '2019-01-04', '2019-01-05',
'2019-01-06', '2019-01-07', '2019-01-08', '2019-01-09', '2019-01-10',
'2019-01-11', '2019-01-13', '2019-01-14', '2019-01-15', '2019-01-16',
'2019-01-17', '2019-01-18', '2019-01-19', '2019-01-20'
]
df = pd.DataFrame({'date': date, 'stream': stream})

这是解决问题的代码:

p_list=[n for n in df.stream if n >0] # we are getting positive values from stream column
p_mean=sum(p_list)/len(p_list) # finding mean (as unusual value threshold) 
n_list=[n for n in df.stream if n <0] #similarly getting negative values
n_mean=sum(n_list)/len(n_list) #finding threshold on the negative side.

获得阈值后(请注意,如果您愿意,可以手动设置这些值,这只是使整个过程自动化的一种尝试。)

p_flags=df.index[(df.stream > p_mean) &((df.stream.shift(-1) <=-.9*df.stream ) | (df.stream.shift(-2)<=-0.9*df.stream
                                                                      )|(df.stream.shift(-3)<=-0.9*df.stream
                                                                        )|(df.stream.shift(-4)<=-0.9*df.stream
                                                                          )|(df.stream.shift(-5)<=-0.9*df.stream
                                                                            ))]

此操作将返回具有匹配条件的行的索引,条件的逻辑非常简单,我们将检查行是否大于p_mean值,如果是,则检查是否有任何p接下来的5行的值小于该值的90%(即流出)|运算符,意味着接下来5行中的任何流出都将意味着该部件返回true。

为了找到负标记索引,我们只有在反转时才有类似的东西:

n_flags=df.index[(df.stream < n_mean) &((df.stream.shift(1) >=0.9*df.stream ) | (df.stream.shift(2)>=0.9*df.stream
                                                                  )|(df.stream.shift(3)>=0.9*df.stream
                                                                    )|(df.stream.shift(4)>=0.9*df.stream
                                                                      )|(df.stream.shift(5)>=0.9*df.stream
                                                                        ))]

如果将符合条件的行添加到数据帧中的列中,只要符合条件的行只需执行以下操作即可:

flags=np.zeros(len(df))
for i1,i2 in zip(n_flags,p_flags):
    flags[i1]=1
    flags[i2]=1

df["flags"]=flags  
print(df)

输出将是:

    date    stream  flags
0   2019-01-01  2   0.0
1   2019-01-02  0   0.0
2   2019-01-03  1   0.0
3   2019-01-04  0   0.0
4   2019-01-05  3   0.0
5   2019-01-06  2   0.0
6   2019-01-07  100 1.0
7   2019-01-08  0   0.0
8   2019-01-09  0   0.0
9   2019-01-10  -95 1.0
10  2019-01-11  3   0.0
11  2019-01-13  0   0.0
12  2019-01-14  2   0.0
13  2019-01-15  -1  0.0
14  2019-01-16  0   0.0
15  2019-01-17  2   0.0
16  2019-01-18  93  1.0
17  2019-01-19  -2  0.0
18  2019-01-20  -89 1.0