Sudhi
Sudhi

Reputation: 421

get corresponding column value from another dataframe pandas

Below are two dataframes that I am comparing. I would like to get the corresponding column value under column Usage in df2 when I am able to match the column Item. Appreciate help.

df1 = pd.DataFrame({ 'Number':[1.0,3.0,4.0,5.0,8.0,12.0,32.0,58.0,72.0] , 'Item': ['Phone', 'Watch', 'Pen', 'Pencil', 'Pencil', 'toolkit', 'box', 'fork', 'toy']})
df2 = pd.DataFrame({'Number':[3.0, 4.0, 8.0, 12.0, 15.0, 32.0, 54.0, 58.0, 72.0], 'Item':['Watch', 'Pen', 'Pencil', 'Eraser', 'bottle', 'box', 'toolkit', 'fork', 'Phone'], 'Usage':['Time', 'Writing', 'Writing', 'Cleaning', 'Water', 'storage', 'Utility', 'Eat', 'Communication']})

df1
   Number     Item
0     1.0    Phone
1     3.0    Watch 
2     4.0      Pen
3     5.0   Pencil
4     8.0   Pencil   
5    12.0  toolkit
6    32.0      box
7    58.0     fork
8    72.0      toy

df2
   Number     Item          Usage
0     3.0    Watch           Time
1     4.0      Pen        Writing
2     8.0   Pencil        Writing
3    12.0   Eraser       Cleaning
4    15.0   bottle          Water
5    32.0      box        storage
6    54.0  toolkit        Utility
7    58.0     fork            Eat
8    72.0    Phone  Communication

Code used for matching is below. It says 'MatchedBoth' even when only the number has matched. This needs to be fixed.

import numpy as np
df3 = df1.copy()
df3['Matching'] = np.nan
df3.loc[(df3.Number.isin(df2.Number)) & (df3.Item.isin(df2.Item)), 'Matching'] = 'MatchedBoth'
df3.loc[(df3.Number.isin(df2.Number)) & (~df3.Item.isin(df2.Item)),'Matching'] = 'Matched Number Only'
df3.Matching.fillna('No Match', inplace=True)

In the same code is there any possibility to embed a return value that can fetch the Usage column value from df2 ,corresponding per matched row. It may be a case where there are multiple rows that could match and hence we might need to get the corresponding Usage column values into a list or something like that in the final output.

Note: In my actual dataframe I have several columns apart from these and hence if I use merge it results in a huge dataframe. I'd just like to create a new column with the list of corresponding matched values found in the Usage column in df2.

Output should look something like below.

df3
   Number     Item             Matching    Usage
0     1.0    Phone             No Match      NaN
1     3.0    Watch          MatchedBoth     Time
2     4.0      Pen          MatchedBoth  Writing
3     5.0   Pencil             No Match      NaN
4     8.0   Pencil          MatchedBoth  Writing 
5    12.0  toolkit  Matched Number Only  Utility
6    32.0      box          MatchedBoth  storage
7    58.0     fork          MatchedBoth      Eat
8    72.0      toy  Matched Number Only     Play

Upvotes: 3

Views: 15641

Answers (1)

Blazina
Blazina

Reputation: 1316

You could try something like this:

df3 = df1.merge(df2, on='Number', how='left')
df3['Matching'] = np.where(df3.Productdetailed == df3.Item, 'Matched', 'No Match')
df3.drop('Productdetailed', axis=1, inplace=True)

which will return the output you indicated in your question.

EDIT after clarification:

def find_match(row):
  if (row.Number in df2.Number.values) & (row.Item in df2.Item.values):
      return "MatchedBoth"
  elif ((row.Number in df2.Number.values) & ~(row.Item in df2.Item.values)):
      return "Matched Number Only"
  else:
      return "No Match"

df3['Matching'] = df3.apply(find_match, axis=1)
df3['Usage'] = df3.Item.map(df2.set_index('Item').Usage)

Upvotes: 3

Related Questions