Я не верю, что так просто адаптировать этот ответ, выделенный @ wen к этому вопросу, так что я предложу решение.
Вы можете создать функцию, которая принимает df
, столбец, который нужно развернуть, и разделитель для этого столбца, и вызывает цепочку столько раз, сколько необходимо.
def expand(df, col, sep=','):
r = df[col].str.split(sep)
d = {c: df[c].values.repeat(r.str.len(), axis=0) for c in df.columns}
d[col] = [i for sub in r for i in sub]
return pd.DataFrame(d)
expand(expand(df, 'test1'), 'test2')
Name test1 test2 Count
0 Emp1 X A 1
1 Emp1 Y A 1
2 Emp2 X A 2
3 Emp2 X B 2
4 Emp2 X C 2
5 Emp3 Z C 3
Предположим, у вас есть
df['test3'] = ['X1|X2|X3', 'X4', 'X5']
такой, что
>>> print(df)
Name test1 test2 Count test3
0 Emp1 X,Y A 1 X1|X2|X3
1 Emp2 X A,B,C 2 X4
2 Emp3 Z C 3 X5
Тогда
>>> expand(df,'test3', '|')
Name test1 test2 Count test3
0 Emp1 X,Y A 1 X1
1 Emp1 X,Y A 1 X2
2 Emp1 X,Y A 1 X3
3 Emp2 X A,B,C 2 X4
4 Emp3 Z C 3 X5
Если вы считаете, что размер столбцов может существенно увеличиться , вы можете определить функцию expand_all
, чтобы избежать появления чего-то вроде expand(expand(expand(expand(........))))))
. Например:
def expand_all(df, cols, seps):
ret = df
for c,s in zip(cols,seps): ret = expand(ret,c,s)
return ret
>>> expand_all(df, ['test1', 'test2', 'test3'], [',', ',', '|'])
Name test1 test2 Count test3
0 Emp1 X A 1 X1
1 Emp1 X A 1 X2
2 Emp1 X A 1 X3
3 Emp1 Y A 1 X1
4 Emp1 Y A 1 X2
5 Emp1 Y A 1 X3
6 Emp2 X A 2 X4
7 Emp2 X B 2 X4
8 Emp2 X C 2 X4
9 Emp3 Z C 3 X5
или как угодно;)
Деталь:
>>> expand(df, 'test1')
Name test1 test2 Count
0 Emp1 X A 1
1 Emp1 Y A 1
2 Emp2 X A,B,C 2
3 Emp3 Z C 3
>>> expand(df, 'test2')
Name test1 test2 Count
0 Emp1 X,Y A 1
1 Emp2 X A 2
2 Emp2 X B 2
3 Emp2 X C 2
4 Emp3 Z C 3
>>> expand(expand(df, 'test2'), 'test1')
Name test1 test2 Count
0 Emp1 X A 1
1 Emp1 Y A 1
2 Emp2 X A 2
3 Emp2 X B 2
4 Emp2 X C 2
5 Emp3 Z C 3
>>> expand(expand(df, 'test2'), 'test1').eq(expand(expand(df, 'test1'), 'test2')).all()
Name True
test1 True
test2 True
Count True
dtype: bool