我有一个类似于以下的数据集:
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])
假设每个帐户每个月有一个值并且没有遗漏日期,您可以使用
groupby_rolling
:
df['output'] = (df.groupby('account').rolling(3)['value']
.sum().eq(3).astype(int).droplevel(0))
print(df)
# Output
date account value output
0 2020-01-31 A 1 0
1 2020-01-31 B 0 0
2 2020-01-31 C 0 0
3 2020-02-28 A 1 0
4 2020-02-28 B 1 0
5 2020-02-28 C 0 0
6 2020-03-31 A 1 1
7 2020-03-31 B 1 0
8 2020-03-31 C 1 0
第二个例子:
df3 = pd.concat([df, df2], ignore_index=True) # <- ignore_index=True
df3['output2'] = (df3.groupby('account').rolling(3)['value']
.sum().eq(3).astype(int).droplevel(0))
print(df3)
# Output
date account value output output2
0 2020-01-31 A 1 0 0
1 2020-01-31 B 0 0 0
2 2020-01-31 C 0 0 0
3 2020-02-28 A 1 0 0
4 2020-02-28 B 1 0 0
5 2020-02-28 C 0 0 0
6 2020-03-31 A 1 1 1
7 2020-03-31 B 1 0 0
8 2020-03-31 C 1 0 0
9 2020-04-30 A 0 0 0
10 2020-04-30 B 1 1 1
11 2020-04-30 C 1 0 0
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})
df["output"] = (~(df.groupby('account')
.cumsum(numeric_only=True)
.agg({'value': lambda n: 0 if n>3 else n})
.subtract(3)
.astype(bool)
)).astype(int)
print(df)
结果
date account value output
0 2020-01-31 A 1 0
1 2020-01-31 B 0 0
2 2020-01-31 C 0 0
3 2020-02-28 A 1 0
4 2020-02-28 B 1 0
5 2020-02-28 C 0 0
6 2020-03-31 A 1 1
7 2020-03-31 B 1 0
8 2020-03-31 C 1 0