簡體   English   中英

Pandas 數據框選擇列表列包含任何字符串列表的行

[英]Pandas dataframe select rows where a list-column contains any of a list of strings

我有一個如下所示的 Pandas DataFrame:

  molecule            species
0        a              [dog]
1        b       [horse, pig]
2        c         [cat, dog]
3        d  [cat, horse, pig]
4        e     [chicken, pig]

我喜歡提取一個只包含那些行的數據幀,其中包含任何selection = ['cat', 'dog'] 所以結果應該是這樣的:

  molecule            species
0        a              [dog]
1        c         [cat, dog]
2        d  [cat, horse, pig]

什么是最簡單的方法來做到這一點?

用於檢測:

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

IIUC 重新創建您的 df 然后將isinany一起使用應該比apply

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

您可以在此處使用帶有apply mask

selection = ['cat', 'dog']

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

對於您在上面作為示例提供的 DataFrame,df1 將是:

molecule    species
0   a   [dog]
2   c   [cat, dog]
3   d   [cat, horse, pig]

在這種情況下,使用 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]

選項 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)

選項 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)

使用 pandas str.contains使用正則表達式):

df[~df["species"].str.contains('(cat|dog)', regex=True)]

輸出:

    molecule    species
1   b   [horse, pig]
4   e   [chicken, pig]

這是一種簡單而基本的方法。 您可以創建一個函數來檢查Selection list中的元素是否存在於熊貓列list

def check(speciesList):
    flag = False
    for animal in selection:
        if animal in speciesList:
            flag = True
    return flag

然后,您可以使用此list根據記錄是否包含選擇列表中的至少一個元素來創建包含TrueFalse的列,並基於它創建一個新的數據框。

df['containsCatDog'] = df.species.apply(lambda animals: check(animals))
newDf = df[df.containsCatDog == True]

我希望它有幫助。

import  pandas as pd
import numpy as np
selection = ['cat', 'dog']
df = pd.DataFrame({'molecule': ['a','b','c','d','e'], 'species' : [['dog'], ['horse','pig'],['cat', 'dog'], ['cat','horse','pig'], ['chicken','pig']]})

df1 = df[df['species'].apply((lambda x: 'dog' in x) )]
df2=df[df['species'].apply((lambda x: 'cat' in x) )]
frames = [df1, df2]
result = pd.concat(frames,join='inner',ignore_index=False)
print("result",result)
result = result[~result.index.duplicated(keep='first')]
print(result)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM