我正在处理一些广告数据,例如电子邮件数据。我有两个数据集:
一个在邮件层面,每个人都说明他们邮寄的日期,以及他们转换的日期。
import pandas as pd
df_emailed=pd.DataFrame()
df_emailed['person']=['A','A','A','A','B','B','B']
df_emailed['day']=[2,4,8,9,1,2,5]
df_emailed
print(df_emailed)
person day
0 A 2
1 A 4
2 A 8
3 A 9
4 B 1
5 B 2
6 B 5
我有一个摘要数据框,说明是否有人转换,以及转换的日期。
df_summary=pd.DataFrame()
df_summary['person']=['A','B']
df_summary['days_max']=[10,5]
df_summary['convert']=[1,0]
print(df_summary)
person days_max convert
0 A 10 1
1 B 5 0
我想将这些结合到最终的数据框中,对每个人说:
我们假设他们在数据帧的最后一天进行转换。
我知道要使用嵌套的for循环来做到这一点,但我认为这非常低效且有点愚蠢。有谁知道这样做的有效方法?
期望的结果
df_final=pd.DataFrame()
df_final['person']=['A','A','A','A','A','A','A','A','A','A','B','B','B','B','B']
df_final['day']=[1,2,3,4,5,6,7,8,9,10,1,2,3,4,5]
df_final['emailed']=[0,1,0,1,0,0,0,1,1,0,1,1,0,0,1]
df_final['convert']=[0,0,0,0,0,0,0,0,0,1,0,0,0,0,0]
print(df_final)
person day emailed convert
0 A 1 0 0
1 A 2 1 0
2 A 3 0 0
3 A 4 1 0
4 A 5 0 0
5 A 6 0 0
6 A 7 0 0
7 A 8 1 0
8 A 9 1 0
9 A 10 0 1
10 B 1 1 0
11 B 2 1 0
12 B 3 0 0
13 B 4 0 0
14 B 5 1 0
谢谢你,节日快乐!
答案 0 :(得分:1)
高级方法涉及修改df_summary
(别名df2
)以获取输出。我们需要
set_index
的{{1}}列上执行days_max
操作。我们还会将名称更改为df2
(稍后会有所帮助)days
分组到groupby
person
对索引进行apply
操作(天数,因此我们会在截至最后一天的每一天获取行数)reindex
填写因重新索引而生成的fillna
列中的NaN convert
为我们稍后设置的assign
创建一个虚拟列。接下来,使用emailed
索引上一操作的结果。我们将使用这些值将相应的df_emailed
单元格设置为emailed
。这是通过MultiIndexing与1
完成的。
最后,使用loc
将索引作为列。
reset_index
哪里
def f(x):
return x.reindex(np.arange(1, x.index.max() + 1))
df = df2.set_index('days_max')\
.rename_axis('day')\
.groupby('person')['convert']\
.apply(f)\
.fillna(0)\
.astype(int)\
.to_frame()\
.assign(emailed=0)
df.loc[df1[['person', 'day']].apply(tuple, 1).values, 'emailed'] = 1
df.reset_index()
person day convert emailed
0 A 1 0 0
1 A 2 0 1
2 A 3 0 0
3 A 4 0 1
4 A 5 0 0
5 A 6 0 0
6 A 7 0 0
7 A 8 0 1
8 A 9 0 1
9 A 10 1 0
10 B 1 0 1
11 B 2 0 1
12 B 3 0 0
13 B 4 0 0
14 B 5 0 1
和
df1 = df_emailed