J'ai deux trames de données. Le premier est une liste d'adresses e-mail

email_ad                   Band 30     Band 40
example_email@gmail.com
sample_email@gmail.com

La seconde est la trame de données suivante

email_ad                 Name       Manager_Name   Manager_Band_level 
example_email@gmail.com. Tom Banks  Boss1          30
sample_email@gmail.com.  Bill Bob   Boss2          40

Je veux mapper chaque e-mail de la première trame de données à la seconde, si l'e-mail correspond, puis vérifier le niveau de la bande du gestionnaire. En vous basant sur le nombre, remplissez l'e-mail du responsable correspondant dans les catégories "Band 30" ou "Band 40".

La trame de données souhaitée est donc la suivante:

email_ad                   Band 30     Band 40
example_email@gmail.com    Boss1
sample_email@gmail.com.                Boss2

Si quelqu'un pouvait s'il vous plaît m'aider pour la syntaxe ce serait incroyable. J'étais également coincé dans la création d'un dictionnaire à partir de seulement certaines colonnes du dataframe. Merci beaucoup!!

0
Robl09 19 avril 2020 à 03:31

2 réponses

Meilleure réponse

Vous pouvez le faire avec un pivot.

pivoted = df.pivot('email_ad', 'Manager_Band_level', 'Manager_Name')
pivoted
# Manager_Band_level          30     40
# email_ad                             
# example_email@gmail.com  Boss1    NaN
# sample_email@gmail.com     NaN  Boss2

Ce format est probablement utilisable tel quel. Mais si vous voulez le nettoyer un peu plus, vous pouvez remplir les valeurs manquantes et l'aplatir.

cleaned = pivoted.fillna('').reset_index()
cleaned
# Manager_Band_level                 email_ad     30     40
# 0                   example_email@gmail.com  Boss1       
# 1                    sample_email@gmail.com         Boss2

Vous pouvez vous débarrasser du nom d'index de colonne gênant, et maintenant incorrect, en réinitialisant columns.

cleaned.columns = list(cleaned.columns)
cleaned
#                   email_ad     30     40
# 0  example_email@gmail.com  Boss1       
# 1   sample_email@gmail.com         Boss2

Si le préfixe Band est important, vous pouvez l'ajouter en même temps.

cleaned.columns = [col if col == 'email_ad' else f'Band {col}' for col in cleaned.columns] 
cleaned
#                   email_ad Band 30 Band 40
# 0  example_email@gmail.com   Boss1        
# 1   sample_email@gmail.com           Boss2
2
mcskinner 19 avril 2020 à 00:51

Essayez d'utiliser la fusion et peut-être une boucle s'il y a plusieurs bandes:

import pandas as pd
from io import StringIO

s1 = '''
email_ad,Band 30,Band 40
example_email@gmail.com,,
sample_email@gmail.com,,
'''

s2= '''
email_ad,Name,Manager_Name,Manager_Band_level
example_email@gmail.com,Tom Banks,Boss1,30
sample_email@gmail.com,Bill Bob,Boss2,40
'''


df1 = pd.read_csv(StringIO(s1))
df2 = pd.read_csv(StringIO(s2))

Et puis fais la fusion

df3 = df1.merge(df2, how='left', left_on='email_ad', right_on='email_ad')
for i in (30,40):
    df3.loc[df3.Manager_Band_level == i, f'Band {i}'] = \
        df3.loc[df3.Manager_Band_level == i, 'Manager_Name']

df3[['email_ad', 'Band 30', 'Band 40']]

#       email_ad    Band 30 Band 40
# 0 example_email@gmail.com Boss1   NaN
# 1 sample_email@gmail.com  NaN Boss2
0
jcaliz 19 avril 2020 à 00:43