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]
4 Réponses :
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))]
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)]
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))]
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]