Вычислить новый столбец на основе ключевого слова и разделения - PullRequest
0 голосов
/ 23 мая 2018

У меня есть такой фрейм данных:

>>> df1
                         overall
0  class1-10/class2-11/class3-13
1  class3-31/class2-22/class1-23
2                abc/def/xyz/prq

Я хочу вычислить 3 столбца class1, class2 и class3, если они найдены в «общем».желаемый o / p

          overall                 class1  class2  class3
0  class1-10/class2-11/class3-13    10    11      13
1  class3-31/class2-22/class1-23    23    22      32
2                abc/def/xyz/prq     NaN  NaN     NaN

Как это можно сделать питоническим способом?Спасибо

Ответы [ 3 ]

0 голосов
/ 23 мая 2018

Может быть заманчиво использовать str.extract, но это соответствует только первому совпадению согласно документам.С другой стороны, str.extractall выводит слишком сложный кадр данных для работы.Мы прибегнем к df.apply.

import re

regex = re.compile(r'(class\d+)-(\d+)')

def func(x):
    data = regex.findall(x[0])
    for class_name, value in data:
        df.loc[x.name, class_name] = value

df.apply(func, axis=1)
print(df)

#                           overall class1 class2 class3
#  0  class1-10/class2-11/class3-13     10     11     13
#  1  class3-31/class2-22/class1-23     23     22     31
#  2                abc/def/xyz/prq    NaN    NaN    NaN
0 голосов
/ 23 мая 2018

Один из способов без регулярных выражений - использовать try / except:

def splitter(x):
    try:
        return [int(i.split('-')[1]) for i in sorted(x.split('/'))]
    except IndexError:
        return [np.nan] * 3

df[['class1', 'class2', 'class3']] = df['overall'].apply(splitter).apply(pd.Series)

print(df)

                         overall  class1  class2  class3
0  class1-10/class2-11/class3-13    10.0    11.0    13.0
1  class3-31/class2-22/class1-23    23.0    22.0    31.0
2                abc/def/xyz/prq     NaN     NaN     NaN
0 голосов
/ 23 мая 2018

Использование -

def split_cols(x):
    for item in x['overall'].split('/'):
        if item.startswith('class'):
            pairs = item.split('-')
            x[pairs[0]] = pairs[1]
    return x
df.apply(split_cols, axis=1)

Выход

    class1  class2  class3  overall
0   10  11  13  class1-10/class2-11/class3-13
1   23  22  31  class3-31/class2-22/class1-23
2   NaN NaN NaN abc/def/xyz/prq

Пояснение

Функция split_cols() позаботитсясоздания дополнительных столбцов.

Сначала разбивается на /, проверяет наличие class в разбиениях

Затем снова разбивается на -, создает столбец спервое разделение и значение для этого столбца как второе разделение.

Затем все это передается через функцию apply

...