Python-как обновить столбец, взяв подстроку из другого столбца?

У меня есть список, который выглядит так: li = ['ShortHair','LongHair','Medium Hair']

Я хочу проверить, содержит ли col2 какую-либо из приведенных выше подстрок, если он берет ее из col2 и обновляет col3. Если это не так, то оставьте col3 как есть.

     col1   col2               col3
0       w   I have ShortHair      U
1       x   LongHair You Have     V
2       y   I have no hair        W
3       z   Look Medium Hair!     L

получить:

     col1   col2               col3
0       w   I have             ShortHair
1       x   You Have           LongHair
2       y   I have no hair        W
3       z   Look !             Medium Hair

EDIT: Если в массиве есть несколько вхождений подстроки, удалите как форму col2, так и обновите col3 первым значением.

Я могу удалить подстроку из col2, но не могу обновить col3. Я старался:

data[data.col2.str.contains('|'.join(li)),"col3"] = data["col2"].map(lambda x: re.findall('|'.join(li),x)[0])

Выдает ошибку IndexError: list index out of range.

Как мне лучше всего это сделать?


person harshit    schedule 05.04.2016    source источник
comment
Что делать, если у вас длинные или короткие волосы? Что должен содержать col3 и почему?   -  person Alexander    schedule 06.04.2016
comment
Удалите оба, оставьте первым. Я обновлю вопрос   -  person harshit    schedule 06.04.2016
comment
@ Александр Я уверен, что этого не произойдет в наборе данных, который я использую. Однако для моих целей достаточно взять первое значение.   -  person harshit    schedule 06.04.2016


Ответы (1)


Создайте образец фрейма данных:

df = pd.DataFrame(
    {'col1': ['w', 'x', 'y', 'z'],
     'col2': ['I have ShortHair', 'LongHair You Have', 'I have no hair', 'Look Medium Hair!'],
     'col3': ['U', 'V', 'W', 'L']})

Используйте лямбда-выражение со списком, чтобы найти все совпадающие слова в каждой строке. Это временный столбец, который будет удален позже.

df['matches'] = df.col2.apply(lambda sentence: [word for word in li if word in sentence])

Создайте маску этих строк, содержащих совпадающие слова.

mask = df.matches.apply(len) > 0

Используя маску и .loc, обновите col3 первым совпадающим словом.

df.loc[mask, 'col3'] = df.loc[mask, 'matches'].str[0]

Используйте лямбда-выражение вместе с reduce, чтобы удалить каждое соответствующее слово из col2:

df.loc[mask, 'col2'] = (
    df.loc[mask, 'col2'].apply(lambda sentence: 
                               reduce(lambda remaining_sentence, word: 
                                      remaining_sentence.replace(word, ''), li, sentence)))

Удалить временный столбец совпавших слов.

del df['matches']

Подтвердите результаты.

>>> df
  col1            col2         col3
0    w         I have     ShortHair
1    x        You Have     LongHair
2    y  I have no hair            W
3    z          Look !  Medium Hair
person Alexander    schedule 06.04.2016