web-dev-qa-db-fra.com

Comment supprimer une liste de lignes de Pandas dataframe?

J'ai une df de dataframe:

>>> df
                  sales  discount  net_sales    cogs
STK_ID RPT_Date                                     
600141 20060331   2.709       NaN      2.709   2.245
       20060630   6.590       NaN      6.590   5.291
       20060930  10.103       NaN     10.103   7.981
       20061231  15.915       NaN     15.915  12.686
       20070331   3.196       NaN      3.196   2.710
       20070630   7.907       NaN      7.907   6.459

Ensuite, je veux supprimer les lignes avec certains numéros de séquence qui sont indiqués dans une liste, supposons que voici [1,2,4], alors à gauche:

                  sales  discount  net_sales    cogs
STK_ID RPT_Date                                     
600141 20060331   2.709       NaN      2.709   2.245
       20061231  15.915       NaN     15.915  12.686
       20070630   7.907       NaN      7.907   6.459

Comment ou quelle fonction peut faire ça?

220
bigbug

Utilisez DataFrame.drop et transmettez-lui une série d'étiquettes d'index:

In [65]: df
Out[65]: 
       one  two
one      1    4
two      2    3
three    3    2
four     4    1


In [66]: df.drop(df.index[[1,3]])
Out[66]: 
       one  two
one      1    4
three    3    2
346
Theodros Zelleke

Notez qu'il peut être important d'utiliser la commande "inplace" lorsque vous souhaitez effectuer une visite en ligne.

df.drop(df.index[[1,3]], inplace=True)

Comme votre question initiale ne renvoie rien, cette commande doit être utilisée. http://pandas.pydata.org/pandas-docs/version/0.17.0/generated/pandas.DataFrame.drop.html

99
user3155053

Vous pouvez également passer à DataFrame.drop l'étiquette elle-même (au lieu d'une série d'étiquettes d'index):

In[17]: df
Out[17]: 
            a         b         c         d         e
one  0.456558 -2.536432  0.216279 -1.305855 -0.121635
two -1.015127 -0.445133  1.867681  2.179392  0.518801

In[18]: df.drop('one')
Out[18]: 
            a         b         c         d         e
two -1.015127 -0.445133  1.867681  2.179392  0.518801

Ce qui équivaut à:

In[19]: df.drop(df.index[[0]])
Out[19]: 
            a         b         c         d         e
two -1.015127 -0.445133  1.867681  2.179392  0.518801
40
danielhadar

Si le DataFrame est énorme et que le nombre de lignes à supprimer est également important, le déplacement simple par index df.drop(df.index[]) prend trop de temps.

Dans mon cas, j'ai un DataFrame multi-indexé de floats avec 100M rows x 3 cols, et j'ai besoin d'en supprimer 10k lignes. La méthode la plus rapide que j'ai trouvée est, assez contre-intuitivement, de take les lignes restantes.

Soit indexes_to_drop un tableau d'index de position à supprimer ([1, 2, 4] dans la question).

indexes_to_keep = set(range(df.shape[0])) - set(indexes_to_drop)
df_sliced = df.take(list(indexes_to_keep))

Dans mon cas, cela prenait 20.5s, alors que le simple df.drop prenait 5min 27s et consommait beaucoup de mémoire. Le DataFrame résultant est le même.

36
Dennis Golomazov

J'ai résolu ce problème plus simplement - en 2 étapes.

Étape 1: commencez par former un cadre de données avec des lignes/données indésirables.

Étape 2: utilisez l'index de cette image de données non désirée pour supprimer les lignes de l'image d'origine.

Exemple:

Supposons que vous ayez une df de données contenant autant de colonnes, y compris "Age", qui est un entier. Supposons maintenant que vous souhaitiez supprimer toutes les lignes avec "Age" comme nombre négatif.

Étape 1: df_age_negative = df [df ['Age'] <0]

Étape 2: df = df.drop (df_age_negative.index, axis = 0)

J'espère que cela est beaucoup plus simple et vous aide.

16

Si je veux supprimer une ligne qui a disons index x, je ferais ce qui suit:

df = df[df.index != x]

Si je voulais supprimer plusieurs index (par exemple, ces index sont dans la liste unwanted_indices), je ferais:

desired_indices = [i for i in len(df.index) if i not in unwanted_indices]
desired_df = df.iloc[desired_indices]
10
Divyansh

Voici un exemple un peu spécifique, je voudrais montrer. Supposons que vous avez plusieurs entrées en double dans certaines de vos lignes. Si vous avez des entrées de chaîne, vous pouvez facilement utiliser des méthodes de chaîne pour trouver tous les index à supprimer.

ind_drop = df[df['column_of_strings'].apply(lambda x: x.startswith('Keyword'))].index

Et maintenant, pour supprimer ces lignes en utilisant leurs index

new_df = df.drop(ind_drop)
4
cyber-math

Dans un commentaire sur la réponse de @ theodros-zelleke, @ j-jones a demandé quoi faire si l'index n'était pas unique. J'ai dû faire face à une telle situation. Ce que j'ai fait était de renommer les doublons de l'index avant d'appeler drop(), à la fois:

dropped_indexes = <determine-indexes-to-drop>
df.index = rename_duplicates(df.index)
df.drop(df.index[dropped_indexes], inplace=True)

rename_duplicates() est une fonction que j'ai définie, passant par les éléments d'index et renommé les doublons. J'ai utilisé le même modèle de renommage que pd.read_csv() utilise sur les colonnes, par exemple, "%s.%d" % (name, count), où name est le nom de la ligne et count, combien de fois il s'est produit auparavant. .

3
mepstein

Déterminer l'indice à partir du booléen comme décrit ci-dessus, par ex.

df[df['column'].isin(values)].index

peut être plus gourmand en mémoire que de déterminer l'index en utilisant cette méthode

pd.Index(np.where(df['column'].isin(values))[0])

appliqué comme si

df.drop(pd.Index(np.where(df['column'].isin(values))[0]), inplace = True)

Cette méthode est utile pour traiter des images de grande taille et une mémoire limitée.

0
Adam Zeldin