如果子字符串列表中的任何值包含在数据框中的任何列中,则过滤行
Posted
技术标签:
【中文标题】如果子字符串列表中的任何值包含在数据框中的任何列中,则过滤行【英文标题】:Filter for rows if any value in a list of substrings is contained in any column in a dataframe 【发布时间】:2021-02-11 11:42:52 【问题描述】:假设我有一个数据框 df 为:
df = pd.DataFrame('Index': [1, 2, 3, 4, 5],
'Name': ['A', 'B', 100, 'C', 'D'],
'col1': [np.nan, 'bbby', 'cccy', 'dddy', 'EEEEE'],
'col2': ['water', np.nan, 'WATER', 'soil', 'cold air'],
'col3': ['watermelone', 'hot AIR', 'air conditioner', 'drink', 50000],
'Results': [1000, 2000, 3000, 4000, 5000])
Out
Index Name col1 col2 col3 Results
1 A NaN water watermelone 1000
2 B bbbY NaN hot AIR 2000
3 100 cccY water air conditioner 3000
4 C dddf soil drink 4000
5 D EEEEE cold air 50000 5000
我有一个清单:matches = ['wat','air']
如何选择col1
或col2
或col3
在matches
中包含i
的所有行。
预期输出:
Index Name col1 col2 col3 Results
1 A NaN water watermelone 1000
2 B bbbY NaN hot AIR 2000
3 100 cccY water air conditioner 3000
5 D EEEEE cold air 50000 5000
【问题讨论】:
【参考方案1】:您可以使用.T
转置数据帧并使用str.contains
按列检查值然后转回(如果用|
分隔,str.contains
也可以传递多个值,这就是为什么我将列表更改为带有matches = '|'.join(matches)
的字符串。
转置数据框的好处是您可以使用按列的 pandas 方法,而不是循环遍历行或长 lambda x:
列表理解。 This technique should have good performance
与 lambda x
与 axis=1
相比答案:
# df = df.set_index('Index')
matches = ['wat','air']
matches = '|'.join(matches)
df = df.reset_index(drop=True).T.fillna('')
df = df.T[[df[col].str.lower().str.contains(matches).values.any() for col in df.columns]]
df
Out[1]:
Name col1 col2 col3
0 A water watermelone
1 B bbbY hot AIR
2 B cccY water air conditioner
4 D EEEEE cold air eat
【讨论】:
@Joe 你能把df = df.T
改成df = df.T.fillna('')
- 查看我更新的答案。
@Joe 我看到你更新了你的问题。我添加了.fillna('')
来处理空格并将case=False
传递给str.contains()
以忽略大写与小写。
嗨@David Erickson,非常感谢。我运行另一个大数据集,给了我"None of [Float64Index([nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,\n ...\n nan, nan, nan, nan, nan, nan, nan, nan, nan, nan],\n dtype='float64', length=4237)] are in the [columns]"
。
@Joe 看起来您的索引上有一个浮点数和 nans。请参阅我的更新答案。我已经用.reset_index(drop=True)
重置了索引
嗨@David Erickson,似乎是因为我的数据库中有浮点数,无法匹配字符串。我添加了df = df.applymap(str)
。现在可以。非常感谢!!!【参考方案2】:
也试试这个:
df = df[df['col1'].str.contains('|'.join(matches))|df['col2'].str.contains('|'.join(matches))|df['col3'].str.contains('|'.join(matches))]
打印:
Name col1 col2 col3
1 A aadY water watermelone
2 B bbbY air hot AIR
3 B cccY water air conditioner
5 D EEEEE cold air eat
【讨论】:
以上是关于如果子字符串列表中的任何值包含在数据框中的任何列中,则过滤行的主要内容,如果未能解决你的问题,请参考以下文章
如何在 python 的另一列中的字符串值中从数据框中的一列中搜索字符串?