如何在Python中基于现有列的文本内容创建新列
如何在Python中基于现有列的文本内容创建新列
嗨,我来帮你搞定这个问题!首先先纠正下你需求里的小笔误:第二个条件里的类别应该是Positive对吧?看你代码里也是append("Positive"),我就按这个来啦。
先说说你原代码为啥会全出Negative:
- 你用的
isin()是检查整个字符串是否完全匹配列表里的值,但你需要的是字符串里包含某个关键词,比如歌曲名是"Evil Ways"的话,isin()就识别不出来,因为整个名字不在你的关键词列表里。 - 你把
df_song['Name'].isin(...)用方括号包起来变成了列表,在Python里非空列表会被判定为True,所以第一个条件永远满足,所有行都被设成Negative了。 - 另外,用循环
append的方式处理DataFrame效率很低,pandas有更高效的向量化操作方法,咱们不用这么麻烦~
下面给你两种靠谱的解决方案,推荐第一种,效率更高:
方法一:用str.contains + np.select(推荐,适合大数据集)
这种是向量化操作,处理速度快,适合数据量大的情况:
import numpy as np import pandas as pd # 先定义好正负关键词列表 negative_words = ["Evil", "Night", "Problem", "Sorrow", "Dead", "Curse", "Venom", "Pain", "Lonely", "Beast"] positive_words = ["Amazing", "Angel", "Perfect", "Sunshine", "Home", "Live", "Friends"] # 构建匹配条件:检查Name列是否包含任意对应关键词 conditions = [ # case=False表示不区分大小写,比如"evil"也能匹配,不需要的话可以去掉 df_song['Name'].str.contains('|'.join(negative_words), case=False), df_song['Name'].str.contains('|'.join(positive_words), case=False) ] # 每个条件对应的结果 choices = ["Negative", "Positive"] # 生成新列,不满足任何条件就默认是Neither df_song['Song Category'] = np.select(conditions, choices, default="Neither")
这里的'|'.join(...)是把关键词列表转成用竖线分隔的字符串,比如"Evil|Night|Problem...",str.contains会自动匹配包含其中任意一个词的字符串,非常方便。
方法二:自定义函数 + apply(适合逻辑复杂的场景)
如果你的匹配逻辑以后可能变复杂,比如要加更多规则,可以写个自定义函数,再用apply应用到每一行:
def get_song_category(name): negative_words = ["Evil", "Night", "Problem", "Sorrow", "Dead", "Curse", "Venom", "Pain", "Lonely", "Beast"] positive_words = ["Amazing", "Angel", "Perfect", "Sunshine", "Home", "Live", "Friends"] # 先检查负面词 for word in negative_words: if word in name: return "Negative" # 再检查正面词 for word in positive_words: if word in name: return "Positive" # 都不满足就返回Neither return "Neither" # 把函数应用到Name列,生成新列 df_song['Song Category'] = df_song['Name'].apply(get_song_category)
这个方法逻辑更直观,适合小数据集,不过速度会比第一种慢一些。
你可以用测试数据验证下:
# 测试用的示例数据 df_song = pd.DataFrame({ "Name": [ "Evil Dead", "Sunshine Day", "My Favorite Song", "Night of the Living Dead", "Angel Eyes" ] })
运行后Song Category列会得到:Negative, Positive, Neither, Negative, Positive,完全符合你的需求~
备注:内容来源于stack exchange,提问作者Prasad Madkaikar




