Pandas dataframe разбивает строку на несколько столбцов с условиями и отсутствующими данными - PullRequest
0 голосов
/ 13 ноября 2018

Итак, у меня есть DataFrame, который выглядит следующим образом:

df = pd.DataFrame({'feature1':[34,45,52],'feature2':[1,0,1],'unparsed_features':["neoclassical, heavy, $2, old, bronze", "romanticism, gold, $5", "baroque, xs, $3, new"]})

df
       feature1  feature2                     unparsed_features
    0        34         1  neoclassical, heavy, $2, old, bronze
    1        45         0                 romanticism, gold, $5
    2        52         1                  baroque, xs, $3, new

Я пытаюсь разбить столбец unparsed_features на 6 столбцов (вес, возраст, цвет, размер, цена и период), но какВы можете видеть, что порядок перемешан и не только, некоторые поля также отсутствуют.

У меня есть общее представление о том, каким может быть каждый столбец, как показано ниже:

main_dict = {
 'weight': ['heavy','light'],
 'age': ['new','old'],
 'colour': ['gold','silver','bronze'],
 'size': ['xs','s','m','l','xl','xxl','xxxl'],
 'price': ['$'],
 'period': ['renaissance','baroque','rococo','neoclassical','romanticism']
}

В идеале я хотел бы, чтобы мой Dataframe выглядел следующим образом:

df
   feature1  feature2                     unparsed_features weight price  age  \
0        34         1  neoclassical, heavy, $2, old, bronze  heavy    $2  old   
1        45         0                 romanticism, gold, $5           $5        
2        52         1                  baroque, xs, $3, new           $3  new   

  size  colour        period  
0       bronze  neoclassical  
1         gold   romanticism  
2   xs               baroque

Я знаю, что первым шагом будет разделить строку запятой, но я потерян после этого.

df['unparsed_features'].str.split(',')

Спасибо за вашу помощь.

Ответы [ 2 ]

0 голосов
/ 13 ноября 2018

Честно говоря, W-B был верным, вам нужно изменить свой диктат, но решить с помощью доступных данных ниже мой подход

for keys in main_dict:
    data_list = []
    for value in df.unparsed_features: # for every row
        for l_data in main_dict[keys]:
            if keys == 'price':
                matching = [v for v in value.split(',') if l_data in v]
            else:
                matching = [v for v in value.split(',') if l_data == v.strip()]

            if matching:
                break

        if matching:
            data_list.append(matching[0])
        else:
            data_list.append(None)

        matching = ''  
    df[keys] = data_list

выход

   feature1  feature2                     unparsed_features  weight   age  \
0        34         1  neoclassical, heavy, $2, old, bronze   heavy   old   
1        45         0                 romanticism, gold, $5    None  None   
2        52         1                  baroque, xs, $3, new    None   new   

    colour  size price        period  
0   bronze  None    $2  neoclassical  
1     gold  None    $5   romanticism  
2     None    xs    $3       baroque  
0 голосов
/ 13 ноября 2018

Не уверен, что есть простой способ сделать это, поскольку данные в 'unparsed_features' имеют разную структуру в каждой строке.Одним из способов может быть использование словаря main_dict, который вы определили, цикл по каждому элементу и использование str.extract с параметром pat, немного отличающимся для price:

for key, list_item in main_dict.items():
    if key =='price':
        df[key] = df.unparsed_features.str.extract('(\$\d+)').fillna('')
    else:
        df[key] = df.unparsed_features.str.extract('((^|\W)' +'|(^|\W)'.join(list_item) + ')').fillna('')

\$\d+ позволяет искать любую цифру после символа $ и (^|\W) искать пробел или начало строки перед любым словом в list_item.

И вы получаете, как и ожидалось:

   feature1  feature2                     unparsed_features  weight   age  \
0        34         1  neoclassical, heavy, $2, old, bronze   heavy   old   
1        45         0                 romanticism, gold, $5                 
2        52         1                  baroque, xs, $3, new           new   

    colour size price        period  
0   bronze         $2  neoclassical  
1     gold         $5   romanticism  
2            xs    $3       baroque  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...