Comment supprimer une liste de lignes de la trame de données Pandas?

258

J'ai un dataframe df:

>>> 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 des lignes avec certains numéros de séquence qui ont indiqué dans une liste, supposons qu'il reste [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 cela?

gros bug
la source
juste pour clarifier, cette question concerne la suppression de lignes avec des valeurs d'index spécifiques. leur utilisation de [1,2,4] est de pointer vers les lignes restantes après la suppression. Il y a des réponses ci-dessous qui font cela.
alchimie

Réponses:

386

Utilisez DataFrame.drop et passez-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
Theodros Zelleke
la source
18
+1 En outre, Suppression de la dernière ligne df.drop (df.tail (1) .index)
Nasser Al-Wohaibi
15
Cette réponse ne fonctionne que si df.index.unique () est identique à df.index, ce qui n'est pas obligatoire pour un Pandas DataFrame. Quelqu'un at-il une solution lorsque les valeurs df.index ne sont pas garanties uniques?
J Jones
2
cela ne vous permet pas d'indexer sur le nom de l'index lui
ingrid
45
Par exemple, si vous voulez être clair, veuillez ne pas utiliser les mêmes chaînes pour les lignes et les colonnes. C'est bien pour ceux qui connaissent déjà vraiment leurs affaires. Frustrant pour ceux qui essaient d'apprendre.
gseattle
2
nouveaux arrivants en python: notez que si vous souhaitez supprimer ces lignes et les enregistrer dans le même cadre de données (en place), vous devez également ajouter le axis=0(0 = lignes, 1 = colonnes) et inplace=Truecomme dans df.drop(df.index[[1,3]], axis=0, inplace=True). @mezzanaccio, si vous savez précisément quels index vous souhaitez remplacer (et aussi en utilisant votre exemple de 0 à n):df.drop(df.index[range(0, n)], axis=0, inplace=True)
mrbTT
47

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

Dans mon cas, j'ai un DataFrame multi-indexé avec des flottants 100M rows x 3 colset je dois en supprimer des 10klignes. La méthode la plus rapide que j'ai trouvée est, de manière assez contre-intuitive, pour takeles lignes restantes.

Soit indexes_to_dropun tableau d'index positionnels à 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, tandis que le simple df.dropprenait 5min 27set consommait beaucoup de mémoire. Le DataFrame résultant est le même.

Dennis Golomazov
la source
43

Vous pouvez également passer à DataFrame.drop l' étiquette elle-même (au lieu de la 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
danielhadar
la source
1
df.drop (df.index [0]) fonctionne également. je veux dire, pas besoin de double square_brackets (avec pandas 0.18.1, au moins)
tagoma
23

J'ai résolu cela d'une manière plus simple - juste en 2 étapes.

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

Étape 2: utilisez l'index de cette trame de données indésirables pour supprimer les lignes de la trame de données d'origine.

Exemple:

Supposons que vous ayez un cadre de données df qui contient autant de colonnes que 'Age' qui est un entier. Supposons maintenant que vous souhaitiez supprimer toutes les lignes avec «Âge» comme nombre négatif.

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

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

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

Krishnaprasad Challuru
la source
1
+1, c'est la seule réponse qui vous indique comment supprimer une ligne en sélectionnant une colonne différente de la première.
Alejo Bernardin
10

Si je veux déposer une ligne qui a disons index x, je ferais ce qui suit:

df = df[df.index != x]

Si je veux supprimer plusieurs indices (disons que ces indices 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]
Divyansh
la source
6

Voici un exemple un peu précis, je voudrais montrer. Supposons que vous ayez 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 rechercher 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)
cyber-math
la source
3

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

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 qui a parcouru les éléments d'index et renommé les doublons. J'ai utilisé le même modèle de changement de nom que celui pd.read_csv()utilisé sur les colonnes, c'est-à-dire, "%s.%d" % (name, count)nameest le nom de la ligne et countcombien de fois il s'est produit précédemment.

mepstein
la source
1

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

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

peut nécessiter plus de mémoire que la détermination de l'index à l'aide de cette méthode

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

appliqué comme ça

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

Cette méthode est utile pour traiter des trames de données volumineuses et une mémoire limitée.

Adam Zeldin
la source
0

Utilisez uniquement l'argument Index pour supprimer la ligne: -

df.drop(index = 2, inplace = True)

Pour plusieurs lignes: -

df.drop(index=[1,3], inplace = True)
kamran kausar
la source
0

Considérons un exemple de trame de données

df =     
index    column1
0           00
1           10
2           20
3           30

nous voulons supprimer les 2e et 3e lignes d'index.

Approche 1:

df = df.drop(df.index[2,3])
 or 
df.drop(df.index[2,3],inplace=True)
print(df)

df =     
index    column1
0           00
3           30

 #This approach removes the rows as we wanted but the index remains unordered

Approche 2

df.drop(df.index[2,3],inplace=True,ignore_index=True)
print(df)
df =     
index    column1
0           00
1           30
#This approach removes the rows as we wanted and resets the index. 
Continent
la source