我有一个类似于以下内容的数据集:
import pandas as pd
date0 = ["2020-01-31"] * 3
date1 = ["2020-02-28"] * 3
date2 = ["2020-03-31"] * 3
date = date0 + date1 + date2
acc = ["A", "B", "C"] * 3
val = [1, 0, 0, 1, 1, 0, 1, 1, 1]
df = pd.DataFrame({"date": date, "account": acc, "value": val})
目标是创建一个名为“output”的新列,该列基于“account”对给定时间序列中二进制列“value”的出现次数进行计数。如果列“val”在一行中显示三个(或N个)1,则输出列为1,否则为0。
对于上述数据集,这将产生:
output = [0, 0, 0, 0, 0, 0, 1, 0, 0]
df["output"] = output
此外,如果时间序列中的第4次迭代是0,那么序列重新开始。当然,如果第4次迭代是1,那么输出是1。
下面的数据集显示,帐户“A”在前3个月就满足了标准,然后帐户恢复,再次开始循环。帐户“B”在第2-4个月满足标准,依此类推。这是大型模拟的一部分,因此矢量化解决方案将是理想的。
date3 = ["2020-04-30"] * 3
val = [0, 1, 1]
acc = ["A", "B", "C"]
output = [0, 1, 0]
df2 = pd.DataFrame({"date": date3, "account": acc, "value": val, "output": output})
df3 = pd.concat([df, df2])
2条答案
按热度按时间bq9c1y661#
假设每个帐户每月有一个值,并且没有缺失日期,则可以使用
groupby_rolling
:对于第二个示例:
hmae6n7t2#
我用了一个更大的数据集进行测试,它运行得很快,效果很好。
我保留了我创建的中间列,以便您看到正在发生的事情。
结果
说明
w
列:3-在示例中,从第6行开始使用numpy进行窗口化(不需要之前的窗口,因为您需要3个连续的1
)。当窗口和为3
时,您有3个连续的1
。mod
:cumsum
模值(引入循环性)对于
cumsum
模值,0%3
和3%3
的mod
列中有0
。当您添加
w
和mod
列时,您实际上过滤掉了包含0%3
的行,例如将w
列中的0
添加到mod
列中的0
,给予0
。另一方面,将
w
列中的3
与mod
列中的0
相加,得到3
(示例中为N值)