4

I have two data frames one with a userId, and gender and another data frame that has online activities of these users.

First Data Frame (df1)

userId, gender
001, F
002, M
003, F
004, M
005, M
006, M

Second data frame (df2)

userId, itemClicked, ItemBought, date
001, 123182, 123212, 02/02/2016
003, 234256, 123182, 05/02/2016
005, 986834, 234256, 04/19/2016
004, 787663, 787663, 05/12/2016
020, 465738, 465738, 03/20/2016
004, 787223, 787663, 07/12/2016

I want to add gender column to the second data frame by looking up the first data frame based on the userId. df2 might have multiple rows per user since its a click data where same user may have click multiple items.

This is very easy to do in MySql but I am trying to figure out to do it in pandas.

for index, row in df2.iterrows():
    user_id = row['userId']
    if user_id in df1['userId']:
        t = df1.loc[df1['userId'] == user_id]
        pdb.set_trace()

Is this the pandas way to so such a task?

3 Answers 3

11
print (df1)
   userId gender
0       1      F
1       2      M
2       3      F
3       4      M
4       5      M
5       6      M

print (df2)
   userId  itemClicked  ItemBought        date
0       1       123182      123212  02/02/2016
1       3       234256      123182  05/02/2016
2       5       986834      234256  04/19/2016
3       4       787663      787663  05/12/2016
4      20       465738      465738  03/20/2016
5       4       787223      787663  07/12/2016

You can use map:

df2['gender'] = df2.userId.map(df1.set_index('userId')['gender'].to_dict())

print (df2)
   userId  itemClicked  ItemBought        date gender
0       1       123182      123212  02/02/2016      F
1       3       234256      123182  05/02/2016      F
2       5       986834      234256  04/19/2016      M
3       4       787663      787663  05/12/2016      M
4      20       465738      465738  03/20/2016    NaN
5       4       787223      787663  07/12/2016      M

Another solution with merge and left join, parameter on can be omit if only column gender is same in both DataFrames:

df = pd.merge(df2, df1, how='left')

print (df)
   userId  itemClicked  ItemBought        date gender
0       1       123182      123212  02/02/2016      F
1       3       234256      123182  05/02/2016      F
2       5       986834      234256  04/19/2016      M
3       4       787663      787663  05/12/2016      M
4      20       465738      465738  03/20/2016    NaN
5       4       787223      787663  07/12/2016      M

Timings:

#len(df2) = 600k
df2 = pd.concat([df2]*100000).reset_index(drop=True)

def f(df1,df2):
    df2['gender'] = df2.userId.map(df1.set_index('userId')['gender'].to_dict())
    return df2


In [43]: %timeit f(df1,df2)
10 loops, best of 3: 34.2 ms per loop

In [44]: %timeit (pd.merge(df2, df1, how='left'))
10 loops, best of 3: 102 ms per loop
Sign up to request clarification or add additional context in comments.

7 Comments

Is this a good approach when dealing with large data frames.10million records?
df2 might have same user more than once since its a click / transaction data. Merge might be problematic right.
I add timings, map solution is the fastest.
Looks like merge is not possible because second data frame doesn't have the gender column. is it possible to do something like this df2['gender'] = NULL, and then do the merge
I think there is no problem, because it is same as (pd.merge(df2, df1, how='left', on='userId')) - it is left join on column userId
|
1

If user_id is the index you can just use :

df2.join(df1)

1 Comment

second data frame have multiple records per same user so its hard to create an index for that data frame.
0

You can try this:

for index, row in df1.iterrows():
   for ind,r in df2.iterrows():
      if r['userId']==row['userId']:
         df2.set_value(ind,'Gender',row['gender'])
         break

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.