web-dev-qa-db-fra.com

Python & Pandas: Comment savoir si une colonne de type liste contient quelque chose?

J'ai un dataframe, qui contient des informations sur les films. Il contient une colonne appelée genre, qui contient la liste des genres auxquels il appartient. Par exemple:

df['genre']

## returns 

0       ['comedy', 'sci-fi']
1       ['action', 'romance', 'comedy']
2       ['documentary']
3       ['crime','horror']
...

Je souhaite savoir comment interroger le bloc de données afin qu'il renvoie le film à un certain genre.

Par exemple, quelque chose comme df['genre'].contains('comedy') renvoie 0 ou 1.

Je sais que pour une liste, je peux faire des choses comme:

'comedy' in  ['comedy', 'sci-fi']

Cependant, dans les pandas, je n'ai pas trouvé quelque chose de similaire, la seule chose que je sache est df['genre'].str.contains(), mais cela n'a pas fonctionné pour le type de liste.

12
cqcn1991

Vous pouvez utiliser apply pour créer mask et ensuite boolean indexing :

mask = df.genre.apply(lambda x: 'comedy' in x)
df1 = df[mask]
print (df1)
                       genre
0           [comedy, sci-fi]
1  [action, romance, comedy]
15
jezrael

en utilisant des ensembles

df.genre.map(set(['comedy']).issubset)

0     True
1     True
2    False
3    False
dtype: bool

df.genre[df.genre.map(set(['comedy']).issubset)]

0             [comedy, sci-fi]
1    [action, romance, comedy]
dtype: object

présenté d'une manière qui me plaît mieux 

comedy = set(['comedy'])
iscomedy = comedy.issubset
df[df.genre.map(iscomedy)]

plus efficace 

comedy = set(['comedy'])
iscomedy = comedy.issubset
df[[iscomedy(l) for l in df.genre.values.tolist()]]

en utilisant str en deux passes
lent! et pas parfaitement précis!

df[df.genre.str.join(' ').str.contains('comedy')]
10
piRSquared

Selon le code source , vous pouvez utiliser .str.contains(..., regex=False).

0
HYRY

Un exemple complet:

import pandas as pd

data = pd.DataFrame([[['foo', 'bar']],
                    [['bar', 'baz']]], columns=['list_column'])
print(data)
  list_column
0  [foo, bar]
1  [bar, baz]

filtered_data = data.loc[
    lambda df: df.list_column.apply(
        lambda l: 'foo' in l
    )
]
print(filtered_data)
  list_column
0  [foo, bar]
0
Adrien Renaud

Un liner utilisant l'indexation booléenne et la compréhension de liste:

searchTerm = 'something'
df[[searchTerm in x for x in df['arrayColumn']]]
0
bloodrootfc