初学者与python - 我正在寻找创建字符串的字典映射,以及相关的值。我有一个数据框,并希望创建一个新列,如果字符串匹配,它将列标记为x。
df = pd.DataFrame({'comp':['dell notebook', 'dell notebook S3', 'dell notepad', 'apple ipad', 'apple ipad2', 'acer chromebook', 'acer chromebookx', 'mac air', 'mac pro', 'lenovo x4'],
'price':range(10)})
例如,我想采用上面的df
并创建一个新列df['company']
并将其设置为字符串映射。
我在考虑做类似
的事情product_map = {'dell':'Dell Inc.',
'apple':'Apple Inc.',
'acer': 'Acer Inc.',
'mac': 'Apple Inc.',
'lenovo': 'Dell Inc.'}
然后我想迭代它来检查df.comp
列,看看每个条目是否包含其中一个字符串,并将df.company
列设置为字典中的值。
不知道如何正确地做到这一点。
答案 0 :(得分:5)
有很多方法可以做到这一点。一种方法是:
def like_function(x):
group = "unknown"
for key in product_map:
if key in x:
group = product_map[key]
break
return group
df['company'] = df.comp.apply(like_function)
答案 1 :(得分:2)
受MaxU similar problem解决方案启发的矢量化解决方案。
x = df.comp.str.split(expand=True)
df['company'] = None
df['company'] = df['company'].fillna(x[x.isin(product_map.keys())]\
.ffill(axis=1).bfill(axis=1).iloc[:, 0])
df['company'].replace(product_map, inplace=True)
print(df)
# comp price company
#0 dell notebook 0 Dell Inc.
#1 dell notebook S3 1 Dell Inc.
#2 dell notepad 2 Dell Inc.
#3 apple ipad 3 Apple Inc.
#4 apple ipad2 4 Apple Inc.
#5 acer chromebook 5 Acer Inc.
#6 acer chromebookx 6 Acer Inc.
#7 mac air 7 Apple Inc.
#8 mac pro 8 Apple Inc.
#9 lenovo x4 9 Dell Inc.
答案 2 :(得分:1)
这是一种有趣的方式,特别是如果你正在学习python。您可以继承dict
并覆盖__getitem__
以查找部分字符串。
class dict_partial(dict):
def __getitem__(self, value):
for k in self.keys():
if k in value:
return self.get(k)
else:
return self.get(None)
product_map = dict_partial({'dell':'Dell Inc.', 'apple':'Apple Inc.',
'acer': 'Acer Inc.', 'mac': 'Apple Inc.',
'lenovo': 'Dell Inc.'})
df['company'] = df['comp'].apply(lambda x: product_map[x])
comp price company
# 0 dell notebook 0 Dell Inc.
# 1 dell notebook S3 1 Dell Inc.
# 2 dell notepad 2 Dell Inc.
# 3 apple ipad 3 Apple Inc.
# 4 apple ipad2 4 Apple Inc.
# 5 acer chromebook 5 Acer Inc.
# 6 acer chromebookx 6 Acer Inc.
# 7 mac air 7 Apple Inc.
# 8 mac pro 8 Apple Inc.
# 9 lenovo x4 9 Dell Inc.
我对此方法的唯一烦恼是,子类化dict
不会在dict.get
语法的同时覆盖[]
。如果可以,我们可以摆脱lambda
并使用df['comp'].map(product_map.get)
。似乎并不是一个明显的解决方案。
答案 3 :(得分:0)
据我所知,pandas没有附带“子字符串映射”方法。 .map()
方法不支持子字符串,.str.contains()
方法仅适用于正则表达式(扩展性不佳)。
您可以通过编写一个简单的函数来获得所需的结果。然后,您可以将.apply()
与lambda function
一起使用以生成所需的“公司”列。额外的好处是,它可使代码保持可读性,并且可以重复使用该功能。希望有帮助。
这应该为您提供所需的“公司”列:
def map_substring(s, dict_map):
for key in dict_map.keys():
if key in s: return dict_map[key]
return np.nan
df['company'] = df['product'].apply(lambda x: map_substring(x, product_map))