是否有等效于df.isin()
和df[col].str.contains()
组合的函数?
例如,假设我有这个系列s = pd.Series(['cat','hat','dog','fog','pet'])
,我想找到s
包含任何['og', 'at']
的所有地方,我想得到除了"宠物"之外的所有东西。
我有一个解决方案,但它相当不雅:
searchfor = ['og', 'at']
found = [s.str.contains(x) for x in searchfor]
result = pd.DataFrame[found]
result.any()
有更好的方法吗?
一个选项就是使用正则表达式|
字符来尝试匹配系列s
中单词中的每个子字符串(仍使用str.contains
)。
您可以通过将searchfor
中的单词与|
:连接来构造正则表达式
>>> searchfor = ['og', 'at']
>>> s[s.str.contains('|'.join(searchfor))]
0 cat
1 hat
2 dog
3 fog
dtype: object
正如@AndyHayden在下面的评论中所指出的,请注意您的子字符串是否有特殊字符,如$
和^
,您希望从字面上匹配它们。这些字符在正则表达式的上下文中具有特定的含义,并将影响匹配。
通过使用re.escape
:转义非字母数字字符,可以使子字符串列表更安全
>>> import re
>>> matches = ['$money', 'x^y']
>>> safe_matches = [re.escape(m) for m in matches]
>>> safe_matches
['\$money', 'x\^y']
当与str.contains
一起使用时,此新列表中的字符串将与每个字符完全匹配。
您可以单独使用str.contains
和使用OR (|)
:的正则表达式模式
s[s.str.contains('og|at')]
或者,您可以将该系列添加到dataframe
,然后使用str.contains
:
df = pd.DataFrame(s)
df[s.str.contains('og|at')]
输出:
0 cat
1 hat
2 dog
3 fog
这里有一个单行lambda也可以工作:
df["TrueFalse"] = df['col1'].apply(lambda x: 1 if any(i in x for i in searchfor) else 0)
输入:
searchfor = ['og', 'at']
df = pd.DataFrame([('cat', 1000.0), ('hat', 2000000.0), ('dog', 1000.0), ('fog', 330000.0),('pet', 330000.0)], columns=['col1', 'col2'])
col1 col2
0 cat 1000.0
1 hat 2000000.0
2 dog 1000.0
3 fog 330000.0
4 pet 330000.0
应用Lambda:
df["TrueFalse"] = df['col1'].apply(lambda x: 1 if any(i in x for i in searchfor) else 0)
输出:
col1 col2 TrueFalse
0 cat 1000.0 1
1 hat 2000000.0 1
2 dog 1000.0 1
3 fog 330000.0 1
4 pet 330000.0 0
也有同样的问题。在不使其过于复杂的情况下,您可以在每个条目之间添加|
,就像fieldname.str.contains("cat|dog")
工作于