Donc je n'ai aucune idée de comment faire cela, et en cherchant une demi-journée, je n'ai pas trouvé ma solution.

Mes données ressemblent à ceci

import pandas as pd

df1 = pd.DataFrame(
    [['132','233','472','098'], ['482','214','980',''], ['107','','',''], 
    ['571','498','',''],], columns=["p1", "p2", "p3", "p4"])
df2 = pd.DataFrame(['532','233','980','132', '298'], columns=["p"])
df1
    p1      p2      p3
0   132     233     472
1   482     214     980
2   107         
3   571     498     

df2
    p
0   532
1   233
2   980
3   132
4   298

Je souhaite faire correspondre les valeurs de la colonne p avec l'une des valeurs des colonnes p {1-3}, et créer une nouvelle colonne contenant la chaîne correspondante.

Donc, dans ce cas, ma sortie souhaitée est

df_output

    p1      p2      p3    matched_p 
0   132     233     472   233
1   482     214     980   980
2   107         
3   571     498     

J'ai essayé ce qui suit

filter1 = df1['p1'].isin(df2['p'])
filter2 = df1['p2'].isin(df2['p'])
filter3 = df1['p3'].isin(df2['p'])
df1['matched_p'] = df2['p'][filter1 | filter2 | filter3]

Cependant, cela m'a donné des résultats insensés.

Des idées sur la façon d'aborder ce problème?

2
Deecer 3 juin 2020 à 21:15

3 réponses

Meilleure réponse

Vous pouvez essayer ceci. Utilisation de df.isin et df.where avec df.max sur l'axe 1.

df1 = df1.replace('',np.nan).astype(float) # to convert everything to float.
df2 = df2.astype(float) #to convert everything to float.
m = df1.isin(df2['p'].to_numpy())
df1['matched_values'] = df1.where(m,0).max(1)
df1

      p1     p2     p3    p4  matched_values
0  132.0  233.0  472.0  98.0           233.0
1  482.0  214.0  980.0   NaN           980.0
2  107.0    NaN    NaN   NaN             NaN
3  571.0  498.0    NaN   NaN             NaN

Si vous ne souhaitez pas convertir vos dtypes en float.

Inspiré de la solution @ Erfan. J'ai combiné nos approches.

df1['matched'] = (df1.where(
                  df1.isin(df2['p'].to_numpy()),'').
                  add(',').sum(1).str.strip(','))
2
Ch3steR 3 juin 2020 à 18:57

Nous pouvons utiliser stack et unstack ici avec isin et quelques manipulations de chaînes. Cela représentera également plusieurs matchs:

d1 = df1.stack()
d1 = d1.where(d1.isin(df2['p'])).unstack().fillna('')
d1 = d1.add(',').sum(axis=1).str.strip(',')

df1['matched_p'] = d1

    p1   p2   p3   p4 matched_p
0  132  233  472  098   132,233
1  482  214  980            980
2  107                         
3  571  498                    
2
Erfan 3 juin 2020 à 18:42
set1 = set(df2['p'])

df1['p'] = df1.apply(lambda x: {x['p1'], x['p2'], x['p3'], x['p4']}.intersection(set1), axis=1)
df1['p'] = df1['p'].map(lambda x: x.pop() if x else '')

0
challasandeep420 3 juin 2020 à 18:33