列表索引超出范围错误 - 熊猫

时间:2016-12-01 00:00:06

标签: python pandas

我有两个数据框。 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

随意提出其他方法。

2 个答案:

答案 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)

使用strjoin

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()

enter image description here