Pandas数据框选择行,其中列表列包含任何字符串列表

Nic*_*coH 8 python dataframe pandas

我有一个像这样的pandas DataFrame:

  molecule            species
0        a              [dog]
1        b       [horse, pig]
2        c         [cat, dog]
3        d  [cat, horse, pig]
4        e     [chicken, pig]
Run Code Online (Sandbox Code Playgroud)

我喜欢提取一个只包含行的DataFrame,其中包含任何行selection = ['cat', 'dog'].所以结果应该是这样的:

  molecule            species
0        a              [dog]
1        c         [cat, dog]
2        d  [cat, horse, pig]
Run Code Online (Sandbox Code Playgroud)

最简单的方法是什么?

用于检测:

selection = ['cat', 'dog']
df = pd.DataFrame({'molecule': ['a','b','c','d','e'], 'species' : [['dog'], ['horse','pig'],['cat', 'dog'], ['cat','horse','pig'], ['chicken','pig']]})
Run Code Online (Sandbox Code Playgroud)

Wes*_*yle 12

你可以maskapply这里使用。

selection = ['cat', 'dog']

mask = df.species.apply(lambda x: any(item for item in selection if item in x))
df1 = df[mask]
Run Code Online (Sandbox Code Playgroud)

对于您在上面作为示例提供的 DataFrame,df1 将是:

molecule    species
0   a   [dog]
2   c   [cat, dog]
3   d   [cat, horse, pig]
Run Code Online (Sandbox Code Playgroud)


Ken*_*alb 12

使用pandas str.contains使用正则表达式):

df[~df["species"].str.contains('(cat|dog)', regex=True)]
Run Code Online (Sandbox Code Playgroud)

输出:

    molecule    species
1   b   [horse, pig]
4   e   [chicken, pig]
Run Code Online (Sandbox Code Playgroud)


Vai*_*ali 7

在这种情况下,使用 Numpy 会比使用 Pandas 快得多,

选项 1:使用 numpy 交集,

mask =  df.species.apply(lambda x: np.intersect1d(x, selection).size > 0)
df[mask]
450 µs ± 21.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

    molecule    species
0   a   [dog]
2   c   [cat, dog]
3   d   [cat, horse, pig]
Run Code Online (Sandbox Code Playgroud)

选项 2:使用 numpy in1d 的类似解决方案,

df[df.species.apply(lambda x: np.any(np.in1d(x, selection)))]
420 µs ± 17.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Run Code Online (Sandbox Code Playgroud)

选项 3:有趣的是,这里使用纯 python 集相当快

df[df.species.apply(lambda x: bool(set(x) & set(selection)))]
305 µs ± 5.22 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Run Code Online (Sandbox Code Playgroud)


WeN*_*Ben 5

IIUC重新创建您的df,然后使用isinwith any应该比apply

df[pd.DataFrame(df.species.tolist()).isin(selection).any(1)]
Out[64]: 
  molecule            species
0        a              [dog]
2        c         [cat, dog]
3        d  [cat, horse, pig]
Run Code Online (Sandbox Code Playgroud)