我有一个名为 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
(Eligible
列中的值为“1”)并且如果客户处于Active
状态(Eligible 列中的值为“1”)事件
列)并且如果从 Visit_1
到 Visit_5
的 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
但是,我不知道如何同时在多个列上执行此操作。有人可以帮忙吗?
最佳答案
我认为,这肯定是一种方法:
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
更新
对于从 Visit_1
到 Visit_N
的可变数量 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
将负责之前使用按位运算符 |
完成的“合并”。
关于python - 通过将条件语句应用于数据类型日期时间和整数的多个其他列来创建列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53932468/