我有一个熊猫数据框,其中包含各种尚未定义的类别(天然气,杂货,快餐等)的信用卡费用。
df1:
Category Date Description Cost
nan 7.1.20 Chipotle Downtown West $8.23
nan 7.1.20 Break Time - Springfield $23.57
nan 7.3.20 State Farm - Agent $94.23
nan 7.3.20 T-Mobile $132.42
nan 7.4.20 Venmo -xj8382dzavvd $8.00
nan 7.6.20 Broadway McDonald's $11.73
nan 7.8.20 Break Time - Townsville $44.23
我想维护第二个数据框,该数据框在描述中搜索关键字并填充“类别”(Category)列。如下:
df2:
item category
mcdonald fast food
state farm insurance
break time gas
chipotle fast food
mobile cell phone
这里的想法是,我将编写代码行以在df1['Description']
中搜索部分字符串,并用df1['Category']
中的值填充df2[category]
。
我敢肯定有一种干净而pythonic的方式来处理此代码,但是下面是我能得到的最接近的方法。以下代码的错误结果是,包含匹配项的df1['Category']
的所有行都设置为df2中的最后一个循环(例如,在这种情况下,所有行都将设置为“手机”)。
for x in df2['item']:
for y in df2['category']:
df1['Category'] = np.where(
df1['Description'].str.lower().str.contains(x),
y,
df1['Category'])
感谢您的帮助!
答案 0 :(得分:1)
您可以使用map,Python的内置difflib获取紧密匹配功能以及lambda表达式。 difflib调用返回一个字符串匹配列表,您可以根据需要调整截止参数以获得或多或少的灵敏度。
import difflib
# you'll need to change both cutoff values here for the lambda to work correctly
df1['Category'] = df1['Description'].map(lambda x: difflib.get_close_matches(x, df2['item'], cutoff=0.3)[0] if len(difflib.get_close_matches(x, df2['item'], cutoff=0.3)) > 1 else 'no match')
print(df1)
Category Date Description Cost
0 chipotle 7.1.20 Chipotle Downtown West $8.23
1 break time 7.1.20 Break Time - Springfield $23.57
2 state farm 7.3.20 State Farm - Agent $94.23
3 mobile 7.3.20 T-Mobile $132.42
4 no match 7.4.20 Venmo -xj8382dzavvd $8.00
5 mcdonald 7.6.20 Broadway McDonald's $11.73
6 break time 7.8.20 Break Time - Townsville $44.23