我有一个如下所示的数据框:
>>> import pandas as pd
>>> df = pd.DataFrame(data = [['app;',1,2,3],['app; web;',4,5,6],['web;',7,8,9],['',1,4,5]],columns = ['a','b','c','d'])
>>> df
a b c d
0 app; 1 2 3
1 app; web; 4 5 6
2 web; 7 8 9
3 1 4 5
我有一个如下所示的输入数组:["app","web"]
对于这些值中的每一个,我想对照数据帧的特定列进行检查并返回如下所示的决定:
>>> df.a.str.contains("app")
0 True
1 True
2 False
3 False
由于 str.contains
只允许我查找单个值,我想知道是否有其他直接方法可以确定相同的值,例如:
df.a.str.contains(["app","web"]) # Returns TypeError: unhashable type: 'list'
我的最终目标不是进行绝对匹配 (df.a.isin(["app", "web"]
),而是执行一个“包含”逻辑,即使这些字符存在于数据框的该单元格中,也返回 true。
注意:我当然可以使用apply方法为相同的逻辑创建我自己的函数,例如:
elementsToLookFor = ["app","web"]
df[header] = df.apply(lambda element: all([a in element for a in elementsToLookFor]))
但我更感兴趣的是为此的最佳算法,因此更喜欢在 Pandas 中使用原生 Pandas 函数,或者下一个最优化的自定义解决方案。
答案 0 :(得分:2)
这也应该有效:
l = ["app","web"]
df['a'].str.findall('|'.join(l)).map(lambda x: len(set(x)) == len(l))
这也应该有效:
pd.concat([df['a'].str.contains(i) for i in l],axis=1).all(axis = 1)
答案 1 :(得分:1)
试试 str.get_dummies
df.a.str.replace(' ','').str.get_dummies(';')[['web','app']].all(1)
0 False
1 True
2 False
3 False
dtype: bool
更新
df['a'].str.contains(r'^(?=.*web)(?=.*app)')
更新 2:(为了确保不区分大小写并且列 dtype 是 str,否则逻辑可能会失败):
elementList = ['app','web']
for eachValue in elementList:
valueString += f'(?=.*{eachValue})'
df[header] = df[header].astype(str).str.lower() #To ensure case insenstivity and the dtype of the column is string
result = df[header].str.contains(valueString)
答案 2 :(得分:1)
这么多方案,哪个最有效
基于 str.contains
的答案通常最快,但 str.findall
在较小的 dfs 上也非常快:
values = ['app', 'web']
pattern = ''.join(f'(?=.*{value})' for value in values)
def replace_dummies_all(df):
return df.a.str.replace(' ', '').str.get_dummies(';')[values].all(1)
def findall_map(df):
return df.a.str.findall('|'.join(values)).map(lambda x: len(set(x)) == len(values))
def lower_contains(df):
return df.a.astype(str).str.lower().str.contains(pattern)
def contains_concat_all(df):
return pd.concat([df.a.str.contains(l) for l in values], axis=1).all(1)
def contains(df):
return df.a.str.contains(pattern)