web-dev-qa-db-fra.com

Comment filtrer des lignes contenant un motif de chaîne à partir d'une image Pandas

Supposons que nous ayons un cadre de données dans Python Pandas qui ressemble à ceci:

df = pd.DataFrame({'vals': [1, 2, 3, 4], 'ids': [u'aball', u'bball', u'cnut', u'fball']})

Ou, sous forme de tableau:

ids    vals
aball   1
bball   2
cnut    3
fball   4

Comment filtrer les lignes contenant le mot clé "ball?" Par exemple, le résultat devrait être:

ids    vals
aball   1
bball   2
fball   4
97
John Knight
In [3]: df[df['ids'].str.contains("ball")]
Out[3]:
     ids  vals
0  aball     1
1  bball     2
3  fball     4
209
Amit
df[df['ids'].str.contains('ball', na = False)] # valid for (at least) pandas version 0.17.1

Explication pas à pas (de l'intérieur vers l'extérieur):

  • df['ids'] sélectionne la colonne ids de la trame de données (techniquement, l'objet df['ids'] est de type pandas.Series)
  • df['ids'].str nous permet d'appliquer des méthodes de chaîne vectorisées (par exemple, lower, contains) à la série.
  • df['ids'].str.contains('ball') vérifie each élément de la série pour savoir si la valeur de l'élément comporte la chaîne 'ball' en tant que sous-chaîne. Le résultat est une série de booléens indiquant True ou False sur l'existence d'une sous-chaîne 'boule'.
  • df[df['ids'].str.contains('ball')] applique le "masque" booléen au cadre de données et renvoie une vue contenant les enregistrements appropriés.
  • na = False supprime les valeurs NA/NaN; sinon, une ValueError peut être retournée.
67
Jubbles
>>> mask = df['ids'].str.contains('ball')    
>>> mask
0     True
1     True
2    False
3     True
Name: ids, dtype: bool

>>> df[mask]
     ids  vals
0  aball     1
1  bball     2
3  fball     4
9
user3820991

Si vous souhaitez définir la colonne sur laquelle vous filtrez comme nouvel index, vous pouvez également envisager d'utiliser .filter ; si vous voulez le conserver dans une colonne séparée, alors _str.contains_ est le chemin à parcourir.

Disons que vous avez

_df = pd.DataFrame({'vals': [1, 2, 3, 4, 5], 'ids': [u'aball', u'bball', u'cnut', u'fball', 'ballxyz']})

       ids  vals
0    aball     1
1    bball     2
2     cnut     3
3    fball     4
4  ballxyz     5
_

et votre plan est de filtrer toutes les lignes dans lesquelles ids contient ball ET définissez ids comme nouvel index, vous pouvez le faire.

_df.set_index('ids').filter(like='ball', axis=0)
_

qui donne

_         vals
ids          
aball       1
bball       2
fball       4
ballxyz     5
_

Mais filter vous permet également de passer une expression rationnelle, de sorte que vous pouvez également filtrer uniquement les lignes où l'entrée de colonne se termine par ball. Dans ce cas, vous utilisez

_df.set_index('ids').filter(regex='ball$', axis=0)

       vals
ids        
aball     1
bball     2
fball     4
_

Notez que maintenant l'entrée avec ballxyz n'est pas incluse car elle commence par ball et ne se termine pas par elle.

Si vous voulez obtenir toutes les entrées commençant par ball, vous pouvez utiliser

_df.set_index('ids').filter(regex='^ball', axis=0)
_

cédant

_         vals
ids          
ballxyz     5
_

Le même fonctionne avec des colonnes; tout ce que vous devez ensuite changer est la partie _axis=0_. Si vous filtrez en fonction des colonnes, il s'agira de _axis=1_.

5
Cleb