Изменение строк фрейма данных на основе списка строк - PullRequest
3 голосов
/ 14 июля 2020

Фон

У меня есть набор данных, в котором есть следующее:

product_title   price
Women's Pant    20.00
Men's Shirt     30.00
Women's Dress   40.00
Blue 4" Shorts  30.00
Blue Shorts     35.00
Green 2" Shorts 30.00

Я создал новый столбец с именем пол, который содержит значения Женщины, Мужчины, или Unisex на основе указанной строки в product_title.

Результат выглядит следующим образом:

product_title   price   gender
Women's Pant    20.00   women
Men's Shirt     30.00   men
Women's Dress   40.00   women
Blue 4" Shorts  30.00   women
Blue Shorts     35.00   unisex
Green 2" Shorts 30.00   women

Подход

Я подошел к созданию нового столбца с помощью операторов if / else:

df['gender'] = ['women' if 'women' in word or 'Blue 4"' in word or 'Green 2"' in word
                else "men" if "men" in word
                else "unisex" 
                for word in df.product_title.str.lower()]

Хотя этот подход работает, он становится очень длинным, когда у меня есть много условий для обозначения женщин, мужчин и мужчин. Есть ли более чистый способ сделать это? Есть ли способ передать список строк вместо длинной цепочки условий или?

Я был бы очень признателен за помощь, так как я новичок в библиотеках python и pandas.

Ответы [ 3 ]

3 голосов
/ 14 июля 2020

IIU C,

import numpy as np
s = df['product title'].str.lower()
df['gender'] = np.select([s.str.contains('men'), 
                          s.str.contains('women|blue 4 shorts|green 2 shorts')], 
                         ['men', 'women'],
                         default='unisex')
1 голос
/ 14 июля 2020

Вот еще одна идея с str.extract и series.map

d = {'women':['women','blue 4"','green 2"'],'men':['men']}
d1 = {val:k for k,v in d.items() for val in v}
pat = '|'.join(d1.keys())
import re
df['gender'] = (df['product_title'].str.extract('('+pat+')',flags=re.I,expand=False)
                .str.lower().map(d1).fillna('unisex'))
print(df)
           product_title  price  gender
0           Women's Pant   20.0   women
1            Men's Shirt   30.0     men
2          Women's Dress   40.0   women
3         Blue 4" Shorts   30.0   women
4            Blue Shorts   35.0  unisex
5  Green 2" Shorts 30.00    NaN   women
1 голос
/ 14 июля 2020

Вы можете попробовать определить свою собственную функцию и запустить ее с помощью выражения apply + lambda:

Создайте функцию, которую вы можете изменить по мере необходимости:

def sex(str):
    '''
    look for specific values and retun value
    '''
    for words in ['women','Blue 4"','Green 2"']:
      if words in str.lower():
          return 'women'
      elif 'men' in str.lower():
          return 'men'
      else:
          return 'unisex'

и после применения в столбец вам нужно проверить значения:

df['gender']=df['product_title'].apply(lambda str: sex(str))

Ура!

РЕДАКТИРОВАТЬ 3: После осмотра и проверки numpy подходящего c от @ansev после @anky comment Мне удалось выяснить, что это может быть быстрее до определенного момента, протестировано с 5000 строками и все еще быстрее, но подход numpy начал догонять. Так что это действительно зависит от того, насколько велик ваш набор данных. Удаляю любые комментарии относительно скорости, которые я считал изначально тестировавшими только на этом маленьком кадре, но это все еще процесс обучения, как вы можете видеть по моему уровню.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...