Use str.get_dummies :
df = df['col'].str.get_dummies('|').replace({0:'no', 1:'yes'})
Or:
d = {0:'no', 1:'yes'}
df = df['col'].str.get_dummies('|').applymap(d.get)
For better performance use MultiLabelBinarizer:
from sklearn.preprocessing import MultiLabelBinarizer
mlb = MultiLabelBinarizer()
df = (pd.DataFrame(mlb.fit_transform(df['col'].str.split('|')) ,
columns=mlb.classes_,
index=df.index)
.applymap(d.get))
print (df)
Action Adventure Crime Drama Fantasy Science Fiction Thriller Western
0 no yes no no no yes yes no
1 yes yes no no yes yes no no
2 yes no yes no no no yes no
3 no yes no yes no no yes yes
Detail:
print (df['col'].str.get_dummies('|'))
Action Adventure Crime Drama Fantasy Science Fiction Thriller \
0 0 1 0 0 0 1 1
1 1 1 0 0 1 1 0
2 1 0 1 0 0 0 1
3 0 1 0 1 0 0 1
Western
0 0
1 0
2 0
3 1
Timings:
df = pd.concat([df] * 10000, ignore_index=True)
In [361]: %timeit pd.DataFrame(mlb.fit_transform(df['col'].str.split('|')) ,columns=mlb.classes_, index=df.index)
10 loops, best of 3: 120 ms per loop
In [362]: %timeit df['col'].str.get_dummies('|')
1 loop, best of 3: 324 ms per loop
In [363]: %timeit pd.get_dummies(df['col'].str.split('|').apply(pd.Series).stack()).sum(level=0)
1 loop, best of 3: 7.77 s per loop