
本教程旨在解决如何在Pandas DataFrame中,根据一个包含关键词-类别映射的字典,为现有列动态添加一个分类列。当字典中的键是DataFrame列值中的子字符串时,直接使用map函数无法满足需求。我们将详细讲解如何利用apply函数结合自定义的lambda表达式,实现高效且灵活的子字符串匹配与分类赋值。
问题背景与挑战
在数据处理中,我们经常需要根据文本描述为数据项添加类别标签。一个常见的场景是,我们拥有一个包含关键词及其对应类别的字典,以及一个dataframe,其中某一列的文本值包含这些关键词。例如,我们有一个商品名称列表,希望根据商品名称中的特定词汇(如“apple”、“grape”)将其归类为“fruit”。
直接使用Pandas的map函数进行字典映射是处理一对一精确匹配的常用方法。然而,当字典的键不是DataFrame列值的精确匹配,而是其子字符串时,map函数将无法直接应用。例如,如果字典是{‘apple’: ‘fruit’},而DataFrame中的项是’apple from happy orchard’,直接df[‘Item’].map(category_dict)将返回NaN,因为它无法找到完全匹配的键。
解决方案:结合apply与自定义匹配逻辑
为了解决子字符串匹配的问题,我们可以利用Pandas DataFrame的apply方法,结合一个自定义的lambda函数。这个lambda函数将遍历字典中的所有键值对,检查字典的键是否作为子字符串存在于DataFrame的当前单元格中。
1. 准备数据与字典
首先,我们定义用于映射的字典和示例DataFrame:
import pandas as pd# 类别字典,键是关键词,值是类别category_dict = { 'apple': 'fruit', 'grape': 'fruit', 'chickpea': 'beans', 'coffee cup': 'tableware'}# 示例DataFramedata = { 'Item': [ 'apple from happy orchard', 'grape from random vineyard', 'chickpea and black bean mix', 'coffee cup with dog decal' ], 'Cost': [15, 20, 10, 14]}df = pd.DataFrame(data)print("原始DataFrame:")print(df)
2. 应用自定义匹配函数
核心的解决方案在于使用df[‘Item’].apply()方法。apply方法会对DataFrame指定列的每一个元素执行一个函数。在这里,我们传递一个lambda函数,该函数接收列中的每个字符串x作为输入,并执行以下逻辑:
遍历字典项: for key, value in category_dict.items() 遍历字典中的每一个关键词和类别。子字符串匹配: if key in x 检查当前的关键词key是否是当前DataFrame项x的子字符串。获取第一个匹配项: next((value for key, value in category_dict.items() if key in x), None) 这行代码使用了一个生成器表达式。它会寻找第一个满足key in x条件的键值对,并返回其对应的value。如果没有任何键匹配成功,next函数将返回其第二个参数None。
# 应用自定义函数添加 'Category' 列df['Category'] = df['Item'].apply( lambda x: next((value for key, value in category_dict.items() if key in x), None))print("n添加 'Category' 列后的DataFrame:")print(df)
输出结果:
原始DataFrame: Item Cost0 apple from happy orchard 151 grape from random vineyard 202 chickpea and black bean mix 103 coffee cup with dog decal 14添加 'Category' 列后的DataFrame: Item Cost Category0 apple from happy orchard 15 fruit1 grape from random vineyard 20 fruit2 chickpea and black bean mix 10 beans3 coffee cup with dog decal 14 tableware
注意事项与进阶考量
性能考量: 对于非常大的DataFrame和/或字典,apply方法在Python循环中执行,可能不是最高效的。如果性能成为瓶颈,可以考虑以下优化:
正则表达式: 使用str.contains()结合正则表达式进行匹配,这通常在C语言层面实现,性能更优。向量化操作: 如果可能,将字典转换为更适合向量化操作的结构。预处理: 如果字典键的数量非常大,可以考虑构建一个Trie树或其他字符串搜索数据结构来加速匹配。
匹配优先级: next()函数会返回第一个找到的匹配项。如果一个DataFrame项可以匹配字典中的多个键(例如,”apple pie”可以匹配”apple”和”pie”),则字典中迭代顺序靠前的键会优先匹配。如果需要特定的优先级,应确保字典的键按照所需的优先级顺序排列(例如,将更具体的键放在前面,或对字典键进行排序)。
无匹配项处理: 当前代码中,如果DataFrame中的项没有匹配到字典中的任何关键词,Category列将赋值为None。你可以根据需求修改next函数的默认值,例如将其设置为’Other’或保留为pd.NA。
# 示例:无匹配项时赋值为 'Unknown'df['Category_with_unknown'] = df['Item'].apply( lambda x: next((value for key, value in category_dict.items() if key in x), 'Unknown'))
大小写敏感性: key in x 是大小写敏感的。如果需要进行大小写不敏感的匹配,应在比较前将key和x都转换为小写:
df['Category_case_insensitive'] = df['Item'].apply( lambda x: next((value for key, value in category_dict.items() if key.lower() in x.lower()), None))
总结
通过灵活运用Pandas的apply函数结合自定义的lambda表达式,我们可以有效地解决在DataFrame中基于字典进行子字符串匹配并添加分类列的问题。这种方法提供了一种强大且可定制的解决方案,适用于各种复杂的文本数据分类场景。在实际应用中,根据数据规模和性能需求,可以进一步考虑优化匹配逻辑和算法。
以上就是如何在Pandas DataFrame中利用字典和子字符串匹配添加分类列的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1373581.html
微信扫一扫
支付宝扫一扫