Отметить, если строка соответствует критериям в течение n дней

Очень интересная нить, мне особенно понравилась идея просто подставить подзаголовок снова. Раньше у меня была аналогичная проблема, и я просто перешел к символу, а затем вернулся к коэффициенту.

   df <- data.frame(letters=letters[1:5],numbers=seq(1:5))
   levels(df$letters)
   ## [1] "a" "b" "c" "d" "e"
   subdf <- df[df$numbers <= 3]
   subdf$letters<-factor(as.character(subdf$letters))
0
задан SMJune 2 March 2019 в 16:04
поделиться

1 ответ

Решение этой проблемы проще с .loc, вы можете использовать следующий код, комментарии в коде объясняют логику:

Эта часть является просто копией вашего кода из вопроса: [ 119]

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, если это так, мы проверяем, любая из следующих пяти строк имеет значение, которое составляет менее 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
0
ответ дан Inder 2 March 2019 в 16:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: