pandas.factorize
и numpy.split
i, u = pd.factorize([*df.A, *np.concatenate(df.B)])
l = df.B.str.len()[:-1].cumsum()
n = len(df)
df.assign(MappedA=i[:n], MappedB=np.split(i[n:], l))
A B MappedA MappedB
0 2f4 [jki, gg4, k6k] 0 [3, 4, 5]
1 1k1 [2f4, gg4, g24] 1 [0, 4, 6]
2 nmk [1k1, g24, 1k1] 2 [1, 6, 1]
Объяснение
- разложить все столбцы
'A'
и 'B'
вместе
- найти длину списков в
'B'
, потому что они помогут определить, где разбить результирующий массив
- Возьмите первый
n
, принадлежащий 'MappedA'
- Возьмите остаток и разделите в соответствии с рассчитанными длинами.
Переменная длина
Предположим, у нас было это df
вместо
df = pd.DataFrame(data={'A': ['2f4', '1k1', 'nmk'], 'B': ['x', 'y', 'z']})
df.at[0, 'B'] = ['jki', 'gg4', 'k6k']
df.at[1, 'B'] = ['2f4', 'gg4', 'g24']
df.at[2, 'B'] = ['1k1', 'g24', '1k1', 'pir']
df
A B
0 2f4 [jki, gg4, k6k]
1 1k1 [2f4, gg4, g24]
2 nmk [1k1, g24, 1k1, pir]
Тогда то же решение приводит к
i, u = pd.factorize([*df.A, *np.concatenate(df.B)])
l = df.B.str.len()[:-1].cumsum()
n = len(df)
df.assign(MappedA=i[:n], MappedB=np.split(i[n:], l))
A B MappedA MappedB
0 2f4 [jki, gg4, k6k] 0 [3, 4, 5]
1 1k1 [2f4, gg4, g24] 1 [0, 4, 6]
2 nmk [1k1, g24, 1k1, pir] 2 [1, 6, 1, 7]