Создание условного столбца фрейма данных с рекурсивным действием в pandas - PullRequest
1 голос
/ 25 мая 2020

У меня есть df, как показано ниже:

time               sb       bn          bs
2020-04-07         True   False
2020-04-08         True   False
2020-04-09         True   False
2020-04-13        False   False
2020-04-14        False   False
2020-04-15        False   False
2020-04-16        False   False
2020-04-17        False   False
2020-04-20        False   False
2020-04-21        False    True
2020-04-22        False   False
2020-04-23        False   False

И условие, как показано ниже:

if -> bn and !sb then True
else if -> bs[1] and sb then False
else -> bs[1]

И мой код:

conditions = [
    (df["bn"] == True) & (df["sb"] == False),
    (df["bs"].shift(1) == True) & (df["sb"] == True)]
choices = ["True", "False"]
df["bs"] = np.select(conditions, choices, default=df["bs"].shift(1))

Я получаю ошибку объекта, который нельзя вызвать . Я думаю, это из-за .shift (1). (Я использую shift (1) для данных за предыдущие дни). Требуемый df с новым столбцом bs должен быть таким:

time              sb       bn          bs
2020-04-07        True     False       False
2020-04-08        True     False       False
2020-04-09        True     False       False
2020-04-13        False    False       False	
2020-04-14        False    False       False
2020-04-15        False    False       False
2020-04-16        False    False       False
2020-04-17        False    False       False
2020-04-20        False    False       False
2020-04-21        False    True        True
2020-04-22        False    False       True
2020-04-23        False    False       True

Что я делаю не так? Спасибо

1 Ответ

2 голосов
/ 25 мая 2020

Поскольку вам нужно предыдущее значение в условии, которое определяет присваивание, я не вижу лучшего способа, чем просто использовать for l oop. Обратите внимание, что нам нужно обрабатывать первую строку отдельно, потому что в этом случае нет предыдущего значения. И вы можете немного сократить условные выражения, установив изначально для всех bs значений False.

df['bs'] = np.repeat(False, len(df))

if df.bn[0] and not df.sb[0]:
    df.bs[0] = True

for i in range(1, len(df)):
    if df.bn[i] and not df.sb[i]:
        df.bs[i] = True
    else:
        if not (df.bs[i-1] and df.sb[i]):
            df.bs[i] = df.bs[i-1]          

df
            sb      bn      bs
2020-04-07  True    False   False
2020-04-08  True    False   False
2020-04-09  True    False   False
2020-04-13  False   False   False
2020-04-14  False   False   False
2020-04-15  False   False   False
2020-04-16  False   False   False
2020-04-17  False   False   False
2020-04-20  False   False   False
2020-04-21  False   True    True
2020-04-22  False   False   True
2020-04-23  False   False   True
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...