![](/img/trans.png)
[英]How to add one column to pandas dataframe based on values in different columns?
[英]Pandas: create a column in one dataframe based on matching values in multiple columns of a different dataframe
我有關於課程出勤率的數據,我的目標是獲取每門課程的出席人數。 不幸的是,領導課程的人也在數據中,需要刪除。 我不能只刪除包含該人姓名的所有行,因為如果他們參加了由其他人主持的課程,他們應該算作參加者。
我有兩個數據框:
new_data
:
|name | email | file | course | date |
|-----|-------|------|--------|--------|
|jo |j@c.i |one |A |6/10/20 |
|bo |b@c.i |one |A |6/10/20 |
|bo |b@c.i |one |B |6/11/20 |
|mo |m@c.i |one |B |6/11/20 |
map_data
:
|lead | course | date |
|-----|--------|--------|
|jo |A |6/10/20 |
|bo |B |6/11/20 |
|mo |B |6/11/20 |
我需要在new_data
中創建一個新列來標記某人是否是潛在客戶。 有一個查找表map_data
指示誰領導了每個 session。
這就是 output 的樣子:
|name | email | file | course | date | lead |
|-----|-------|------|--------|--------|------|
|jo |j@c.i |one |A |6/10/20 |1 |
|bo |b@c.i |one |A |6/10/20 |0 |
|bo |b@c.i |one |B |6/11/20 |1 |
|mo |m@c.i |one |B |6/11/20 |1 |
請注意, bo
不是course
A
的主角,而是B
中的主角。
編輯:有些課程有多個線索: B
有兩個。 這導致在我使用此線程中建議的解決方案解決此問題的一些嘗試中出現重復問題。
這是一個有限的例子,但不同的人在不同的日子跑相同的課程。 jo
可能會在不同的日期運行course
A
對於new_data
中的每一行,如果name
、 course
和date
與map_data
中的值匹配,我需要將new_data["lead"]
標記為1
。 在所有其他情況下, new_data["lead"]
應該是0
。
我被卡住了,因為我不知道如何使用三列在數據幀之間進行查找。
像這樣的東西會起作用嗎?
tmp = new_data.set_index(["name","course", "date"]).join(map_data.set_index(["lead","course", "date"]))
tmp["is_lead"] = tmp["name"] == tmp["lead"]
tmp["is_lead"] = tmp["is_lead"].astype('int')
這是一個可能有幫助的 function:
def lead(df, df_map):
# Get the leads names, course and date in a single string, like a code. e.g 'joA6/10/20'
leads = [str(df_map.lead[j])+str(df_map.course[j])+str(df_map.date[j]) for j in range(df_map.shape[0])]
# loop to create the data for LEAD column
lead_col = [1 if str(df.name[i])+str(df.course[i])+str(df.date[i]) in leads else 0 for i in range(df.shape[0])]
# insert LEAD column in the df and return
df['lead'] = lead_col
return df
我的輸入示例:
name email file course date
jo j@c.i one A 6/10/20
bo b@c.i one B 6/11/20
bo b@c.i one B 6/10/20
mo mo@i one B 6/10/20
jay j@i one B 6/11/20
Map:
lead course date
jo A 6/10/20
bo B 6/11/20
mo B 6/10/20
Output:
name email file course date lead
jo j@c.i one A 6/10/20 1
bo b@c.i one B 6/11/20 1
bo b@c.i one B 6/10/20 0
mo mo@i one B 6/10/20 1
jay j@i one B 6/11/20 0
使用pd.crosstab() ,這將把領導頻率制成表格。 適當地堆疊和重命名列。 這給出了一個新的 dataframe ,您可以使用.combine_first()將其加入 new_data 。 這會附加由交叉表產生的所有行。 刪除任何 NaN。
請注意df=map_data
:
鏈式解決方案
new_data.combine_first(pd.crosstab([df.lead, df.course], df.date).stack().reset_index().rename(columns={'lead':'name',0:'lead'})).dropna()
分步解決
#Crosstab
df3=pd.crosstab([df.lead, df.course], df.date).stack().reset_index().rename(columns={'lead':'name',0:'lead'})
#Combine_first
res=new_data.combine_first(df3).dropna()
print(res)
course date email file lead name
0 A 6/10/20 j@c.i one 0.0 jo
1 A 6/10/20 b@c.i one 1.0 bo
2 B 6/11/20 b@c.i one 1.0 bo
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.