如果某人一年内在会员名单中获胜,我想在“获胜者”栏中输入0或1。 有一本获奖字典。
award_winner = {'2010':['Momo','Dahyum'],'2011':['Nayeon','Sana'],'2012':['Moon','Jihyo']}
这是数据帧:
df = pd.DataFrame({'member':[['Jeong-yeon','Momo'],['Jay-z','Bieber'],['Kim','Moon']],'year' : ['2010','2011','2012']})
从数据框架中,我想根据字典查看每年(数据框架的年份)是否有获奖者。
例如,让我们看第一行。 Momo于2010年获胜,Moon于2012年获胜,因此数据框的预期输出应如下所示:
所以这是到目前为止的代码:
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)
或
在这里,我无法分配行。我希望代码能根据字典中的年份查找是否有获奖者。因此,代码应逐行检查,但我不能,
我总结了在栈溢出中要问的问题。但是有超过10,000行,我认为如果使用熊猫“ apply”来解决这个问题是可能的。 已经在不使用熊猫的情况下尝试了两次for loop,这花费了太长时间。 我试图使用groupby()但我想知道我应该如何使用.. 喜欢。
df['winner'] = df['year'].groupby().apply(winner_classifier)..?
您能帮我吗?
谢谢:)
答案 0 :(得分:1)
您可以在此处使用Python的set()功能轻松比较两个任意长度的列表。
我将其写为逐行迭代器,因为我不确定您想要的结果是什么样(例如,您只想要对/错,还是要记录“获胜者”每一行?)。有了1万行,逐行遍历数据帧应该不是问题。
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
答案 1 :(得分:1)
从字典创建df,以便以后可以合并
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]
现在合并并找到奖励与会员的交集
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