web-dev-qa-db-fra.com

Comment supprimer des lignes d'un DataFrame pandas basé sur une expression conditionnelle

J'ai un pandas DataFrame et je veux en supprimer les lignes où la longueur de la chaîne d'une colonne est supérieure à 2. Je sais que je peux utiliser df.dropna() pour supprimer les lignes contenant une NaN, mais je ne vois pas comment supprimer des lignes basées sur une expression conditionnelle. 

La réponse pour cette question semble très proche de ce que je veux - il me semble que je devrais être capable de faire quelque chose comme ceci:

df[(len(df['column name']) < 2)]

mais je viens de recevoir l'erreur:

KeyError: u'no item named False'

Quelqu'un peut-il me dire ce que je fais mal?

162
sjs

Lorsque vous faites len(df['column name']), vous n’obtenez qu’un nombre, à savoir le nombre de lignes dans le DataFrame (c'est-à-dire la longueur de la colonne elle-même). Si vous souhaitez appliquer len à chaque élément de la colonne, utilisez df['column name'].map(len). Alors essayez

df[df['column name'].map(len) < 2]
96
BrenBarn

Je cherchais une solution à ce problème et je suis tombé sur une approche évidente consistant à filtrer le bloc de données et à réattribuer le bloc de données d'origine afin

df = df[df["score"] > 50]

Dans les pandas, vous pouvez utiliser str.len avec votre limite et utiliser le résultat booléen pour la filtrer. 

df[df['column name'].str.len().lt(2)]
3
Wen-Ben

Si vous souhaitez supprimer des lignes de trame de données sur la base d'une condition compliquée sur la valeur de la colonne, l'écriture de la manière indiquée ci-dessus peut être compliquée. J'ai la solution plus simple suivante qui fonctionne toujours. Supposons que vous souhaitiez supprimer la colonne avec 'en-tête', obtenez-la d'abord dans une liste.

text_data = df ['name']. tolist ()

appliquez maintenant une fonction sur chaque élément de la liste et mettez-la dans une série de pandas:

text_length = pd.Series ([func (t) pour t dans text_data])

dans mon cas, j'essayais simplement d'obtenir le nombre de jetons:

text_length = pd.Series ([len (t.split ()) pour t dans text_data])

ajoutez maintenant une colonne supplémentaire contenant les séries ci-dessus dans le bloc de données:

df = df.assign (text_length = text_length .values)

nous pouvons maintenant appliquer une condition à la nouvelle colonne, telle que:

df = df [df.text_length> 10]

Un filtre passe-bas/passe-haut pour le texte avec ceci est le suivant:

def pass_filter(df, label, length, pass_type):

    text_data = df[label].tolist()

    text_length = pd.Series([len(t.split()) for t in text_data])

    df = df.assign(text_length = text_length .values)

    if pass_type == 'high':
        df = df[df.text_length  >  length]

    if pass_type == 'low':
        df = df[df.text_length  <  length]

    df = df.drop(columns=['text_length'])

    return df

1
jayanti prasad