2
votes

Filtrer les lignes uniquement si la liste des colonnes contient des valeurs d'une autre liste

J'ai un dataframe, où une colonne est une liste:

   colA colB
0   ID2 [A] 
1   ID3 [B] 
2   ID4 [A, B] 

Je souhaite filtrer les lignes afin que seules les lignes qui contiennent uniquement les valeurs d'une autre liste soient sélectionnées. Cependant, toute ligne contenant une valeur non présente dans une autre liste ne doit pas être sélectionnée.

   colA colB
0   ID1 [A, B, C] #not selected because it contains C
1   ID2 [A] #Valid
2   ID3 [B] #Valid
3   ID4 [A, B] #Valid
4   ID5 [C, D] #Not valid - Either values not present in valid list

Résultat attendu

valid_list = ['A', 'B']

trame de données finale:

import pandas as pd 

data = [{'colA': 'ID1', 'colB': ['A', 'B', 'C']}, 
        {'colA': 'ID2', 'colB': ['A']}, 
        {'colA': 'ID3', 'colB': ['B']}, 
        {'colA': 'ID4', 'colB': ['A', 'B']},
        {'colA': 'ID5', 'colB': ['C', 'D']}] 

df = pd.DataFrame(data) 
df 

    colA    colB
0   ID1     [A, B, C]
1   ID2     [A]
2   ID3     [B]
3   ID4     [A, B]
4   ID5     [C, D]


0 commentaires

4 Réponses :


1
votes

Utilisez issubset avec sets:

print (df)
  colA    colB
1  ID2     [A]
2  ID3     [B]
3  ID4  [A, B]

df = df[df.colB.map(lambda x: set(x) <= set(valid_list))]

df = df[df.colB.map(lambda x: set(x).issubset(valid_list))]


0 commentaires

1
votes

en utilisant np.setdiff1d

 colA    colB
1  ID2     [A]
2  ID3     [B]
3  ID4  [A, B]

OU

df[~df.colB.apply(lambda x: len(np.setdiff1d(x,valid_list)) >= 1)]

df[df.colB.apply(lambda x: False if len(np.setdiff1d(x,valid_list)) >= 1 else True)]


0 commentaires

1
votes

Vous pouvez également appliquer une fonction pour obtenir le masque:

print(df)
  colA    colB
1  ID2     [A]
2  ID3     [B]
3  ID4  [A, B]

df = df[df.colB.apply(lambda lst: all(x in valid_list for x in lst))]


0 commentaires

2
votes

Utilisez np.isin et all

df[df.colB.map(lambda x: np.isin(x, valid_list).all())]

Out[217]:
  colA    colB
1  ID2  [A]
2  ID3  [B]
3  ID4  [A, B]


0 commentaires