How do i use apply function in python while moving row by row

Viewed 98

I'm trying to put 0 or 1 in the 'winner' column if there are somebody who won in the member list in a year. There is a dictionary with an award winner.

award_winner = {'2010':['Momo','Dahyum'],'2011':['Nayeon','Sana'],'2012':['Moon','Jihyo']}

And This is the data frame:

df = pd.DataFrame({'member':[['Jeong-yeon','Momo'],['Jay-z','Bieber'],['Kim','Moon']],'year' : ['2010','2011','2012']})

enter image description here

From the data frame, I would like to see if there's any award winner in each year(dataframe's year) based on the dictionary.

For example, let's look at the first row. Momo won in 2010 and Moon won in 2012 so the desired output of the dataframe should be like this:

enter image description here

So this is the code so far:

df['winner'] = 0 #empty column
def winner_classifier():
  for i in range(len(df['member'])): #searching if there are any award winner in df
    if df['member'][row][i] in award_winner[df['year'][row]]: #I couldn't make row to 
      return 1
    else:
      continue
df['winner'] = df['member'].apply(winner_classifier) 

or

In here, I can't assign row. I want the code to look up if there's any winner based on the year from dictionary. So the code should go row by row and check but i can't,,

I summarized the problem like this to ask in stack overflow. But there are more than 10,000 rows and I thought it would be possible if use pandas 'apply' to solve this problem. Already tried double for loop without using pandas and that took too long. I tried to use groupby() but i was wonderinghow should i use.. like..

df['winner'] = df['year'].groupby().apply(winner_classifier)..?

Could you help me with this?

Thank you :)

2 Answers

You can make use of Python's set() capability here to easily compare two lists of arbitrary length.

I have written this as a row-wise iterator as I wasn't entirely sure what you wanted the result to look like (ie. do you just want a true/false, or do you want to record the "winner" each row?). With 10k rows it shouldn't be a problem to iterate over the dataframe row by row.

for index, row in df.iterrows():
    members_who_were_winners = set(row.member) & set(award_winner[row.year])
    if len(members_who_were_winners) > 0:
        # You could also write the member name to a new column etc
        df.at[index, 'winner_this_year'] = True
    else:
        df.at[index, 'winner_this_year'] = False

Create a df from dictionary so that you can merge it later

winners = pd.DataFrame({
    'year' : list(award_winner.keys()),
     'winner': list(award_winner.values())})
print (winners)
   year          winner
0  2010  [Momo, Dahyum]
1  2011  [Nayeon, Sana]
2  2012   [Moon, Jihyo]

Now merge and find the intersection of awards with members

result = df.merge(winners, on="year")
result['result']  = result.apply(
    lambda x: len(set(x.member).intersection(x.winner)) != 0, axis=1)
result = result.drop(['winner'], axis=1)
print (result)
               member  year  result
0  [Jeong-yeon, Momo]  2010    True
1     [Jay-z, Bieber]  2011   False
2         [Kim, Moon]  2012    True
Related