使用apply

时间:2018-05-26 19:29:27

标签: python python-3.x pandas dataframe

我有一个非常简单的数据框用于测试目的。它看起来像这样:

movieId | title     | genres              | Drama | Action | Comedy
1       | Toy Story | {'Drama', 'Comedy'} | 0     | 0      | 0

我想在相应的列中反映布尔值中的genres集,因此所需的结果将是:

movieId | title     | genres              | Drama | Action | Comedy
1       | Toy Story | {'Drama', 'Comedy'} | 1     | 0      | 1

所以我尝试使用以下代码:

def ttb(genreset):                                                
    return tuple(1 if g in genreset else 0 for g in all_genres)

all_genres = ('Drama', 'Action', 'Comedy')

df.T.loc[all_genres, :] = df.apply(lambda x: ttb(x.loc['genres']), axis=1) 

但是这导致了一个我无法真正理解的错误:

ValueError: shape mismatch: value array of shape (19,) could not be broadcast to indexing result of shape (19,1)

我是否需要以某种方式将apply的返回值转换为具有固定大小或者为什么它没有像我期望的那样工作?我尝试了更多的数据,但总是得到同样的错误。谷歌搜索错误给了很多结果,但没有为我提供可行的解决方案。

1 个答案:

答案 0 :(得分:3)

致电str.join,然后致电str.get_dummies

v = df.genres.str.join(',').str.get_dummies(sep=',')

或者,如果需要明确添加“操作”,请使用reindex

v = (df['genre']
     .str.join(',')
     .str.get_dummies(sep=',')
     .reindex(
         ['Comedy', 'Action', 'Drama'], 
         axis=1, 
         fill_value=0
     )
)

print(v)
   Comedy  Action  Drama
0       1       0      1

如果你有许多独特的价值观并且你不确定它们是什么,你总能找到他们的联盟:

u = set().union(*df.genres.tolist())

现在,使用u重新构建结果索引。

如果您需要将其添加回原始DataFrame,请使用concat

df = pd.concat([df, v], axis=1)