从这个示例数据开始...
import pandas as pd
start_data = {"person_id": [1, 1, 1, 1, 2], "nid": [1, 2, 3, 4, 1],
"beg": ["Jan 1 2018", "Jan 5 2018", "Jan 10 2018", "Feb 5 2018", "Jan 25 2018"],
"end": ["Feb 1 2018", "Mar 4 2018", "", "Oct 18 2018", "Nov 10 2018"]}
df = pd.DataFrame(start_data)
df["beg"] = pd.to_datetime(df["beg"])
df["end"] = pd.to_datetime(df["end"])
起点:
person_id nid beg end
0 1 1 2018-01-01 2018-02-01
1 1 2 2018-01-05 2018-03-04
2 1 3 2018-01-10 NaT
3 1 4 2018-02-05 2018-10-18
4 2 1 2018-01-25 2018-11-10
目标输出:
person_id date 1 2 3 4
1 2018-01-01 1 0 0 0
1 2018-01-05 1 1 0 0
1 2018-01-10 1 1 1 0
1 2018-02-01 0 1 1 0
1 2018-02-05 0 1 1 1
1 2018-03-04 0 0 1 1
1 2018-10-18 0 0 1 0
2 2018-01-25 1 0 0 0
2 2018-11-10 0 0 0 0
我正在尝试将所有事件的 nid
绑定(bind)到关联的 person_id
然后这将根据最新的 date
加入另一个数据框> 少于过时的事件栏。最后,这将成为预测模型输入的一部分。
做类似 pd.get_dummies(df["nid"])
的操作得到这个输出:
1 2 3 4
0 1 0 0 0
1 0 1 0 0
2 0 0 1 0
3 0 0 0 1
4 1 0 0 0
因此这需要移动到表示生效日期的不同索引,按 person_id
分组,然后聚合以匹配目标输出。
特别奖励给任何能够想出一种可以适当利用 Dask 的方法的人.由于可扩展性,这就是我们用于管道其他部分的内容。这可能是一个白日梦,但我想我会把它发出去看看会返回什么。
最佳答案
题目好难,只能想到numpy
广播来加速for循环
s=df.set_index('person_id')[['beg','end']].stack()
l=[]
for x , y in df.groupby('person_id'):
y=y.fillna({'end':y.end.max()})
s1=y.beg.values
s2=y.end.values
t=s.loc[x].values
l.append(pd.DataFrame(((s1-t[:,None]).astype(float)<=0)&((s2-t[:,None]).astype(float)>0),columns=y.nid,index=s.loc[[x]].index))
s=pd.concat([s,pd.concat(l).fillna(0).astype(int)],1).reset_index(level=0).sort_values(['person_id',0])
s
Out[401]:
person_id 0 1 2 3 4
beg 1 2018-01-01 1 0 0 0
beg 1 2018-01-05 1 1 0 0
beg 1 2018-01-10 1 1 1 0
end 1 2018-02-01 0 1 1 0
beg 1 2018-02-05 0 1 1 1
end 1 2018-03-04 0 0 1 1
end 1 2018-10-18 0 0 0 0
beg 2 2018-01-25 1 0 0 0
end 2 2018-11-10 0 0 0 0
关于python - 有效日期范围单热编码 groupby,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56385056/