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
上面的代码标记所有流入的流量,而不考虑流出的条件。
答案 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