这是以下文章的后续内容:Pandas dataframe select rows where a list-column contains any of a list of strings
我希望能够从选择列表中选择包含确切一对字符串的行(其中selection = ['cat','dog'])。
启动df:
molecule species
0 a [dog]
1 b [horse, pig]
2 c [cat, dog]
3 d [cat, horse, pig]
4 e [chicken, pig]
我想要的df
molecule species
2 c [cat, dog]
我尝试了以下操作,它仅返回了列标签。
df[pd.DataFrame(df.species.tolist()).isin(selection).all(1)]
答案 0 :(得分:1)
一种方法:
df['joined'] = df.species.str.join(sep=',')
selection = ['cat,dog']
filtered = df.loc[df.joined.isin(selection)]
这不会找到排序不同的案例(即'dog,cat'
或'horse,cat,pig'
),但是如果这不是问题,那就很好用了。
答案 1 :(得分:0)
这会找到任何东西。
import pandas as pd
selection = ['cat', 'dog']
mols = pd.DataFrame({'molecule':['a','b','c','d','e'],'species':[['dog'],['horse','pig'],['cat','dog'],['cat','horse','pig'],['chicken','pig']]})
mols.loc[np.where(pd.Series([all(w in selection for w in mols.species.values[k]) for k in mols.index]).map({True:1,False:0}) == 1)[0]]
如果您想查找至少包含列表中元素(也可能包含其他元素)的任何行,请使用:
mols.loc[np.where(pd.Series([all(w in mols.species.values[k] for w in selection) for k in mols.index]).map({True:1,False:0}) == 1)[0]]
这是矩阵作为选择器的一个有趣应用。使用转置的 mols 将 0 和 1 的向量相乘,这些向量指出 mol 中的哪些行符合您的标准:
mols.to_numpy().T.dot(pd.Series([all(w in mols.species.values[k] for w in selection) for k in mols.index]).map({True:1,False:0}))
另一种(更易读的)解决方案是将条件为 True 的列分配给 mols,将其映射到 0 和 1 并查询该列等于 1 的 mols。