pandas получить значения из вложенных ячеек excel

Рейтинг: 0Ответов: 1Опубликовано: 27.03.2023

Есть dataframe полученный из xlsx файла:
введите сюда описание изображения

В колонке contact может находится произвольное количество данных (mail, phone, skype и т.д) для account.
Каким образом можно перенести вложенные данные для account в новые колонки? Т.е если для account 10001 есть mail и 3 телефона, на выходе надо получить заполненные account, code, descr, mail, phone_1, phone_2, phone_3. Для account 10002 будут заполнены только phone_1, phone_2. В конечной таблице вся информация по account в одной строке (1 acc = 1 строка)... Совсем мозг сломал. Натолкните пожалуйста в какую сторону копать. Прошу прощения. исходник выглядит:
введите сюда описание изображения
Как должен выглядеть результат:
введите сюда описание изображения

df = pd.DataFrame({
    'account': [10001, 10001, 10001, 10001, 10002, 10002, 10058, 10058, 10058],
    'code': [1732, 1732, 1732, 1732, 148, 148, 131, 131, 131],
    'descr': ['test', 'test', 'test', 'test', 'test', 'test', 'test', 'test', 'test'],
    'contact': ['e-mail:XXXXXXX1@XXX.XXX', 'phone: XXXXXXXX1', 'phone: XXXXXXXX2',
                'phone: XXXXXXXX3', 'phone: XXXXXXXX4', 'phone: XXXXXXXX45',
                'e-mail:XXXXXXX2@XXX.XXX', 'phone: XXXXXXXX11', 'phone: XXXXXXXX12']
})

Ответы

▲ 3Принят

Сначала режем сплитом по двоеточию столбец 'contact' на два столбца - сам контакт и тип. Добавляем порядковый номер к типу через группировку по аккаунт+тип. Потом выносим в мультииндекс аккаунт и тип и делаем unstack() для поворота. Далее соединяем часть исходного фрейма с ранее перевернутой частью с помощью merge()

df = pd.DataFrame({
    'account': [10001, 10001, 10001, 10001, 10002, 10002, 10058, 10058, 10058],
    'code': [1732, 1732, 1732, 1732, 148, 148, 131, 131, 131],
    'descr': ['test', 'test', 'test', 'test', 'test', 'test', 'test', 'test', 'test'],
    'contact': ['e-mail:XXXXXXX1@XXX.XXX', 'phone: XXXXXXXX1', 'phone: XXXXXXXX2',
                'phone: XXXXXXXX3', 'phone: XXXXXXXX4', 'phone: XXXXXXXX45',
                'e-mail:XXXXXXX2@XXX.XXX', 'phone: XXXXXXXX11', 'phone: XXXXXXXX12']})

df[['type', 'contact']] = df.contact.str.split(':', expand=True)
df['type'] = df.type + '_' + (df.groupby(['account', 'type']).cumcount() + 1).astype(str)
df1 = df[['account', 'contact', 'type']].set_index(['account', 'type']).unstack().droplevel(0, axis=1).reset_index()
df = df[['account', 'code', 'descr']].drop_duplicates('account').merge(df1, on='account', how='right')
print(df)
   account  code descr          e-mail_1      phone_1      phone_2     phone_3
0    10001  1732  test  XXXXXXX1@XXX.XXX    XXXXXXXX1    XXXXXXXX2   XXXXXXXX3
1    10002   148  test               NaN    XXXXXXXX4   XXXXXXXX45         NaN
2    10058   131  test  XXXXXXX2@XXX.XXX   XXXXXXXX11   XXXXXXXX12         NaN