Создайте столбец, применив условный оператор к нескольким другим столбцам dtypes datetime и integer. - PullRequest
0 голосов
/ 26 декабря 2018

У меня есть датафрейм с именем df, который выглядит примерно так (за исключением случаев, когда количество посещений достигает 74, а количество клиентов - несколько сотен - я упростил его здесь).

Client    Visit_1     Visit_2     Visit_3     Visit_4     Visit_5     Eligible  Active     
Client_1  2016-05-10  2016-05-25  2016-06-10  2016-06-25  2016-07-10  0         0  
Client_2  2017-05-10  2017-05-25  2017-06-10  2017-06-25  2017-07-10  0         0  
Client_3  2018-09-10  2018-09-26  2018-10-10  2018-10-26  2018-11-10  1         0  
Client_4  2018-10-10  2018-10-26  2018-11-10  2018-11-26  2018-12-10  1         1  

Я хочусоздать новый столбец с именем Visit in Window с двумя значениями, 0 и 1. Я хочу установить Visit in Window равным 1, если клиент равен Eligible (значение '1' в столбце Eligible) И если клиентравно Active (значение '1' в столбце Active) И если любой из из 5 столбцов от Visit_1 до Visit_5 содержит дату, которая находится между 2018-10-25 и 2018-12-15.

Итак, я хочу получить фрейм данных, который выглядит следующим образом:

Client    Visit_1     Visit_2     Visit_3     Visit_4     Visit_5     Eligible  Active  Visit_in_Window    
Client_1  2016-05-10  2016-05-25  2016-06-10  2016-06-25  2016-07-10  0         0       0  
Client_2  2017-05-10  2017-05-25  2017-06-10  2017-06-25  2017-07-10  0         0       0  
Client_3  2018-09-10  2018-09-26  2018-10-10  2018-10-26  2018-11-10  1         0       0  
Client_4  2018-10-10  2018-10-26  2018-11-10  2018-11-26  2018-12-10  1         1       1  

Я могу сделать это для одного столбца, используя следующий код

df['Visit_in_Window'] = 0
df.loc[((df.Eligible == 1) & (df.Active == 1) &
        (df.Visit_1 > '2018-10-24') & 
        (df.Visit_1 < '2018-12-16')), 'Visit_in_Window'] = 1

Однако я не знаю, как выполнить это действие для нескольких столбцов одновременно.Кто-нибудь может помочь?

Ответы [ 2 ]

0 голосов
/ 26 декабря 2018

Один из возможных способов сделать это такой же, как вы предложили в вопросе, но с дополнительными «или» утверждениями

df['Visit_in_Window'] = 0
df.loc[
            (df.Eligible == 1) & 
            (df.Active == 1) & 
            ( ((df.Visit_1 > '2018-10-24') & (df.Visit_1 < '2018-12-16')) |
              ((df.Visit_2 > '2018-10-24') & (df.Visit_2 < '2018-12-16')) |
              ((df.Visit_3 > '2018-10-24') & (df.Visit_3 < '2018-12-16')) |
              ((df.Visit_4 > '2018-10-24') & (df.Visit_4 < '2018-12-16')) |
              ((df.Visit_5 > '2018-10-24') & (df.Visit_5 < '2018-12-16')) 
            ) , 

'Visit_in_Window'] = 1
0 голосов
/ 26 декабря 2018

Я думаю, это, безусловно, способ сделать это:

import pandas as pd
from collections import OrderedDict

df = pd.DataFrame(OrderedDict([
    ("Client", ["Client_1", "Client_2", "Client_3", "Client_4"]),
    ("Visit_1", ["2016-05-10", "2017-05-10", "2018-09-10", "2018-10-10"]),
    ("Visit_2", ["2016-05-25", "2017-05-25", "2018-09-26", "2018-10-26"]),
    ("Visit_3", ["2016-06-10", "2017-06-10", "2018-10-10", "2018-11-10"]),
    ("Visit_4", ["2016-06-25", "2017-06-25", "2018-10-26", "2018-11-26"]),
    ("Visit_5", ["2016-07-10", "2017-07-10", "2018-11-10", "2018-12-10"]),
    ("Eligible", [0, 0, 1, 1]),
    ("Active", [0, 0, 0, 1])
]))

df["Visit_in_Window"] = (
    df["Eligible"] & df["Active"] & (
        (("2018-10-25" < df["Visit_1"]) & (df["Visit_1"] < "2018-12-15")) |
        (("2018-10-25" < df["Visit_2"]) & (df["Visit_2"] < "2018-12-15")) |
        (("2018-10-25" < df["Visit_3"]) & (df["Visit_3"] < "2018-12-15")) |
        (("2018-10-25" < df["Visit_4"]) & (df["Visit_4"] < "2018-12-15")) |
        (("2018-10-25" < df["Visit_5"]) & (df["Visit_5"] < "2018-12-15"))
    )
)

print(df.to_string(index=False))

Что печатает:

   Client     Visit_1     Visit_2     Visit_3     Visit_4     Visit_5  Eligible  Active Visit_in_Window
 Client_1  2016-05-10  2016-05-25  2016-06-10  2016-06-25  2016-07-10         0       0           False
 Client_2  2017-05-10  2017-05-25  2017-06-10  2017-06-25  2017-07-10         0       0           False
 Client_3  2018-09-10  2018-09-26  2018-10-10  2018-10-26  2018-11-10         1       0           False
 Client_4  2018-10-10  2018-10-26  2018-11-10  2018-11-26  2018-12-10         1       1            True

Обновление

Для переменного числа N столбцов от Visit_1 до Visit_N это должно работать:

N = 5
visits = pd.DataFrame([(("2018-10-25" < df["Visit_" + str(i)]) & (df["Visit_" + str(i)] < "2018-12-15")) for i in range(1, N + 1)])
print(visits)
df["Visit_in_Window"] = df["Eligible"] & df["Active"] & visits.any()

Что печатает:

             0      1      2      3
Visit_1  False  False  False  False
Visit_2  False  False  False   True
Visit_3  False  False  False   True
Visit_4  False  False   True   True
Visit_5  False  False   True   True

Как видите,* только в столбцах 2 и 3 (клиент 3 и 4) True, где они посещали в пределах диапазона дат.any позаботится о «слиянии», которое было сделано заранее с помощью побитового оператора |.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...