Python 如何根据多列中的字符串匹配选择数据帧中的行
我认为这个确切的问题还没有得到回答,所以还是这样吧 我有一个熊猫数据框,我想选择a列或B列中包含字符串的所有行 假设数据帧如下所示:Python 如何根据多列中的字符串匹配选择数据帧中的行,python,pandas,dataframe,Python,Pandas,Dataframe,我认为这个确切的问题还没有得到回答,所以还是这样吧 我有一个熊猫数据框,我想选择a列或B列中包含字符串的所有行 假设数据帧如下所示: d = {'id':["1", "2", "3", "4"], 'title': ["Horses are good", "Cats are bad", "Frogs are nice", "Turkeys are the best"], 'description':["Horse epitome", "Cats bad but horses
d = {'id':["1", "2", "3", "4"],
'title': ["Horses are good", "Cats are bad", "Frogs are nice", "Turkeys are the best"],
'description':["Horse epitome", "Cats bad but horses good", "Frog fancier", "Turkey tome, not about horses"],
'tags':["horse, cat, frog, turkey", "horse, cat, frog, turkey", "horse, cat, frog, turkey", "horse, cat, frog, turkey"],
'date':["2019-01-01", "2019-10-01", "2018-08-14", "2016-11-29"]}
dataframe = pandas.DataFrame(d)
其中:
id title description tag date
1 "Horses are good" "Horse epitome" "horse, cat" 2019-01-01
2 "Cats are bad" "Cats bad" "horse, cat" 2019-10-01
3 "Frogs are nice" "Frog fancier, horses good" "horse, frog" 2018-08-14
4 "Turkey are best" "Turkey tome" "turkey, horse" 2016-11-29
假设我想创建一个新的数据框,其中包含列标题或列说明,而不是列标记(或任何其他列)中带有字符串horse
(忽略大写)的行
结果应该是(删除第2行和第4行):
我在一篇专栏文章中看到了一些答案,例如:
dataframe[dataframe['title'].str.contains('horse')]
但我不确定(1)如何向该语句中添加多个列,以及(2)如何使用string.lower()
之类的内容对其进行修改,以删除列值中的大写字母以匹配字符串
提前谢谢 如果要为测试指定列,一种可能的解决方案是连接所有列,然后使用和case=False进行测试:
s = dataframe['title'] + dataframe['description']
df = dataframe[s.str.contains('horse', case=False)]
或者为每列创建条件,并按位或与|
链接:
df = dataframe[dataframe['title'].str.contains('horse', case=False) |
dataframe['description'].str.contains('horse', case=False)]
另外,如果需要,请通过~
为不匹配的指定列,以按位为非测试链解决方案指定列,并通过~
为反转条件指定列:
df = dataframe[s.str.contains('horse', case=False) &
~dataframe['tags'].str.contains('horse', case=False)]
对于第二种解决方案,在所有列周围添加()
,并用或链接:
df = dataframe[(dataframe['title'].str.contains('horse', case=False) |
dataframe['description'].str.contains('horse', case=False)) &
~dataframe['tags'].str.contains('horse', case=False)]]
编辑:
Like@WeNYoBen评论说,您可以将其添加到末尾,例如:
您可以在与每列对应的序列上使用“逻辑或”运算符|
:
filtered = df[df['title'].str.contains('horse', case=False) |
df['description'].str.contains('horse', case=False)]
如果有许多列,可以使用reduce操作:
import functools
import operator
colnames = ['title', 'description']
mask = functools.reduce(operator.or_, (df[col].str.contains('horse', case=False) for col in colnames))
filtered = df[mask]
请删除第一个解决方案,因为在我的回答中。谢谢你的帮助,第一个解决方案对我来说很好,尽管我很感激一行!
filtered = df[df['title'].str.contains('horse', case=False) |
df['description'].str.contains('horse', case=False)]
import functools
import operator
colnames = ['title', 'description']
mask = functools.reduce(operator.or_, (df[col].str.contains('horse', case=False) for col in colnames))
filtered = df[mask]