簡體   English   中英

Pandas:根據不同dataframe的多列中的匹配值,在一個dataframe中創建一列

[英]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中的每一行,如果namecoursedatemap_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM