![](/img/trans.png)
[英]pandas - how to organised dataframe based on date and assign new values to column
[英]Pandas, how can I avoid the use of iterrow (how to assign values to a new column in a dataframe based on the values from another dataframe)
我有三個不同的實體: Opportunity 、 Account 、 Activity 。
我需要以一種特殊的方式將它們結合起來。 讓我解釋一下它們之間的關系:
另外,值得注意的是
{ opp_id; opp_date; acc_id}
{ opp_id; opp_date; acc_id}
{ act_id; act_date; acc_id }
{ act_id; act_date; acc_id }
我想要實現的是在機會日期前 X 天完成的活動數量插入機會。
我目前正在這樣做:
a_new_df = pd.DataFrame(columns=['acc_id',"opp_id", "opp_date", "act_90", "act_180"])
for index, opp_row in Opportunity.iterrows():
account = opp_row["acc_id"]
opportunity = opp_row["opp_id"]
opp_date = opp_row["opp_date"]
act_90, act_180 = 0, 0
for index, act_row in activities_step_7.iterrows():
if acc == act_row["acc_id"]:
days = (pd.to_datetime(opp_date) - pd.to_datetime(act_row["act_date"])).days
if days<=90:
act_90+=1
elif days<=180:
act_180+=1
events_df = events_df.append({
"acc_id": account,
"opp_id": opportunity,
"opp_date" : dat,
"act_90" : act_90,
"act_180" : act_180,
}, ignore_index=True)
最后,我在Opportunity和這個新的 df之間做了一個merge()
。 當然,手術需要很長時間。 但是,我不知道如何改善這一點。
主要問題是我需要在 Opportunity 中插入一些統計信息,這些統計信息需要來自 Opportunity 和 Activity 的數據,但我不能事先合並它們,因為對於每個機會我有多個活動要考慮(而且你不能做左連接當您有重復項時)
任何想法? 非常感謝!
編輯 1
如果這是我的機會表:
opp_date acc_id opp_id
0 05.08.2019 acc1 opp1
1 25.03.2019 acc2 opp2
2 27.08.2019 acc1 opp3
3 02.09.2019 acc1 opp4
4 22.07.2019 acc3 opp5
這是我的活動表:
acc_id act_date
0 acc1 25.07.2019
1 acc1 26.07.2019
2 acc1 31.07.2019
3 acc1 28.07.2019
4 acc1 02.09.2019
5 acc1 02.09.2019
6 acc1 31.07.2019
7 acc1 02.09.2019
8 acc1 24.07.2019
9 acc1 25.07.2019
10 acc2 31.03.2019
11 acc3 31.07.2019
12 acc2 24.03.2019
13 acc3 13.05.2019
14 acc3 05.02.2019
15 acc3 30.05.2016
16 acc3 30.11.2017
17 acc3 11.04.2016
18 acc3 19.01.2018
19 acc3 19.01.2018
20 acc2 24.03.2019
21 acc1 04.08.2019
22 acc1 20.10.2019
那么預期的 output 是:
opp_date acc_id opp_id act_90 act_180
0 05.08.2019 acc1 opp1 4 4
1 25.03.2019 acc2 opp2 0 0
2 27.08.2019 acc1 opp3 7 8
3 02.09.2019 acc1 opp4 0 0
4 22.07.2019 acc3 opp5 2 2
您可以使用一些pandas
內置函數代替您的 for 循環。 這個結果與您在問題中發布的“預期輸出”有點不同,但我認為它符合您的描述。
讓我們稱您的第一個 dataframe df1
和您的第二個df2
。
我們可以通過將其寫為 function 並apply
它來計算有多少活動適合您的條件,而不是在行上迭代:
def count_activities(row, act_df, days):
return (act_df['act_date'].between(row['opp_date'] -pd.Timedelta(days=days), row['opp_date'])
& (act_df['acc_id']==row['acc_id'])).sum()
由於我們在上面的 function 中進行了計數,因此加入不是問題:
def add_count_activities_column(opp_df, act_df, days):
return opp_df.join(opp_df.apply(lambda row: count_activities(row,act_df,days), axis=1).rename('act_{}'.format(days)))
結果:
df3 = add_count_activities_column(df1, df2, 90)
df3 = add_count_activities_column(df3, df2, 180)
我的df3
是
opp_date acc_id opp_id act_90 act_180
0 2019-05-08 acc1 opp1 4 4
1 2019-03-25 acc2 opp2 2 2
2 2019-08-27 acc1 opp3 7 8
3 2019-02-09 acc1 opp4 3 3
4 2019-07-22 acc3 opp5 2 2
ps - 我會使用opp_id
作為索引,使用df1.set_index('opp_id', inplace=True)
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.