Один лайнер
df.loc[df.index.repeat(df.profile_id.str.count(', ') + 1)].assign(
profile_id=', '.join(df.profile_id).split(', '))
profile_id user birthday
0 123 test1 day1
0 124 test1 day1
1 131 test2 day2
1 132 test2 day2
Разбитый
sep = ', '
idx = df.index.repeat(df.profile_id.str.count(sep) + 1)
new = sep.join(df.profile_id).split(sep)
df.loc[idx].assign(profile_id=new)
profile_id user birthday
0 123 test1 day1
0 124 test1 day1
1 131 test2 day2
1 132 test2 day2
Numpy ломтик вместо loc
также получите новый индекс
sep = ', '
col = 'profile_id'
p = df[col]
i = np.arange(len(df)).repeat(p.str.count(sep) + 1)
pd.DataFrame({
col: sep.join(p).split(sep),
**{c: df[c].values[i] for c in df if c != col}
}, columns=df.columns)
profile_id user birthday
0 123 test1 day1
1 124 test1 day1
2 131 test2 day2
3 132 test2 day2