我正在处理一些广告数据,例如电子邮件数据。我有两个数据集:
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
谢谢你,节日快乐!
高级方法涉及修改df_summary
(别名df2
)以获得我们的输出。我们需要
set_index
在days_max
的df2
专栏上的操作。我们还将名称更改为days
(稍后会有所帮助)groupby
加入person
apply
对指数进行reindex
操作(天数,所以我们得到每天排到最后一天的行)fillna
填充由于重新索引而生成的convert
列中的NaNsassign
为我们稍后设置的emailed
创建一个虚拟列。接下来,使用df_emailed
索引上一个操作的结果。我们将使用这些值将相应的emailed
细胞设置为1
。这是通过使用loc
的MultiIndexing完成的。
最后,使用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
和,
df2 = df_summary