Как получить информацию из колонки и разбить ее на несколько колонок?

Столкнулся с проблемой в процессе обработки DataFrame и получения данных из колонки:

Исходный DataFrame:

№     Собственники                                 Рег.дата
0  Ильина Светлана Сергеевна (9 000 руб., 90%)     1177746680143
   Храпов Иван Филиппович (1 000 руб., 10%)
1  Помигуев Сергей Викторович (10 000 руб., 100%)  1187746820117
2  Гинзбург Семен Эдуардович (10 000 руб., 33,33%) 1157746553161
   Буюкян Андрей Завенович (10 000 руб., 33,3%)
   Афонасьев Максим Альбертович (10 000 руб., 33.3%)
3  Nan                                             1089847058322

Цель - необходимо из колонки Собственники получить ФИО всех собственников и их доли владения, разложить в каждую колонку:

№     owner_1                 share_1   owner_2                share_2   owner_3  share_3     Рег.дата
 0  Ильина Светлана Сергеевна  90%      Храпов Иван Филиппович   10%     Nan    Nan      1177746680143     
 1  Помигуев Сергей Викторович 100%      Nan                     Nan      Nan   Nan      1187746820117
 2  Гинзбург Семен Эдуардович 33,33%) Буюкян Андрей Завенович    33,3%  АМА    33.3%     1157746553161
 3  Nan                                                                                  1089847058322

Я извлёк при помощи regex ФИО и доли процентов, но дальше как это все красиво распределить по колонкам, не получается.

def owner_fio(stroka):
    try:
        sample = '[А-ЯЁ][а-яё]+\s+[А-ЯЁ][а-яё]+(?:\s+[А-ЯЁ][а-яё]+)?'
        s = re.findall(sample, stroka)
        return s
    except:
        return None
def owner_share(stroka):
    try:
        sample = '\d{1,}%'
        s = re.findall(sample, stroka)
        return s
    except:
        return None

Когда применил функции выше, получились новые колонки ФИО и % в виде списка:

№     owner                                                                      share        Рег.дата
 0  [Ильина Светлана Сергеевна,Храпов Иван Филиппович]                         [90%,10% ]  1177746680143     
 1  [Помигуев Сергей Викторович]                                               [100% ]     1187746820117
 2  [Гинзбург Семен Эдуардович,Буюкян Андрей Завенович,Афонасьев Максим Альбертович] [33.33%,33.3%,33.3%]     1157746553161
 3  Nan                                                                        Nan         1089847058322

Как теперь все это корректно и граммотно разбить по колонкам?

И мне кажется regex по извлечению доли процентов тоже некорректен, т.к. не учитывает, если доля процентов не целое число.


Ответы (1 шт):

Автор решения: MaxU

Попробуйте так:

import re
from itertools import chain

owners = (df
          ["Собственники"]
          .str.extractall(r"([а-яё\s]+)\s+", flags=re.I)
          .unstack()
          .add_prefix("owner_")
          .droplevel(0, axis=1))

shares = (df
          ["Собственники"]
          .str.extractall(r"(\d{1,3}[\.,]?\d{1,3}%)")
          .unstack()
          .add_prefix("share_")
          .droplevel(0, axis=1))

r = owners.join(shares)
cols = list(chain(*zip(owners.columns, shares.columns)))
r = r[cols]

результат:

In [82]: r
Out[82]:
match                     owner_0 share_0                   owner_1 share_1                        owner_2 share_2
0       Ильина Светлана Сергеевна     90%    Храпов Иван Филиппович     10%                            NaN     NaN
1      Помигуев Сергей Викторович    100%                               NaN                            NaN     NaN
2       Гинзбург Семен Эдуардович  33,33%   Буюкян Андрей Завенович   33,3%   Афонасьев Максим Альбертович   33.3%
→ Ссылка