背景
我有一个数据集,其中包含以下内容:
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
我根据product_title中指定的字符串创建了一个名为性别的新列,其中包含值Women,Men或Unisex。
输出看起来像这样:
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()]
尽管这种方法行得通,但是当我有很多条件来标记女性vs男性vs男女通用时,它变得很长。有没有更清洁的方法可以做到这一点?有没有办法让我传递一个字符串列表,而不用一连串的or条件?
我非常感谢帮助,因为我是python和pandas库的新手。
答案 0 :(得分:3)
IIUC,
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 :(得分:1)
您可以尝试定义自己的函数并使用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: 在环顾四周并在@anky评论之后检查来自@ansev的numpy方法后,我发现到特定点它可能会更快,用5000行进行测试,并且仍然更快,但是numpy方法开始迎头赶上。因此,这实际上取决于数据集的大小。 将会删除我最初只是在这个小框架上测试的速度方面的任何注释,从我的水平来看,这仍然是一个学习过程。
答案 2 :(得分:1)
这里是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