我有两个数据框。 df1看起来像 -
MovieName Actors
lights out Maria Bello
legend Tom Hardy*Emily Browning*Christopher Eccleston*David Thewlis
df2看起来像 -
ActorName Gender
Tom male
Emily female
Christopher male
我想在df1'lemale_actors'和'male_actors'中添加两列,分别包含该特定电影中女性和男性演员的数量。演员是男性还是女性是基于df2完成的。
这就是我在做什么 -
def func(actors, gender):
actors = [act.split()[0] for act in actors.split('*')]
n_gender = df2.Gender[df2.Gender==gender][df2.ActorName.isin(actors)].count()
return n_gender
df1['male_actors'] = df1.Actors.apply(lambda x: func(x, 'male'))
df1['female_actors'] = df1.Actors.apply(lambda x: func(x, 'female'))
此代码为我提供了列表索引超出范围错误。
请注意 -
如果gender.csv中没有特定名称,请不要将其计入总数中。 如果电影中只有一个演员,而且它在gender.csv中不存在,那么它的计数应为零。
结果应为 -
MovieName Actors male_actors female_actors
lights out Maria Bello 0 0
legend Tom Hardy*Emily Browning*Christopher Eccleston*David Thewlis 2 1
随意提出其他方法。
答案 0 :(得分:2)
这个怎么样?
df1['Male'] = df1.Actors.apply(lambda x: len(pd.concat( [df2[(df2.ActorName == name) & (df2.Gender == 'male')] for name in x.split('*')] )))
df1['Female'] = df1.Actors.apply(lambda x: len(pd.concat( [df2[(df2.ActorName == name) & (df2.Gender == 'female')] for name in x.split('*')] )))
答案 1 :(得分:1)
使用str
和join
d2 = df2.set_index('ActorName')
d1 = df1.set_index('MovieName')
方法1
split
d1.join(d1.Actors.str.split('*', expand=True).stack() \
.str.split(expand=True)[0].map(d2.Gender) \
.groupby(level='MovieName') \
.value_counts().unstack()).fillna(0).reset_index()
方法2
extractall
d1.join(d1.Actors.str.extractall('((?P<first>[^*]+)\s+(?P<last>[^*]+))') \
['first'].map(d2.Gender).groupby(level='MovieName') \
.value_counts().unstack()).fillna(0).reset_index()