J'ai un dataframe pandas où les colonnes sont nommées comme:

0,1,2,3,4,.....,n

Je voudrais supprimer toutes les 3 colonnes afin d'obtenir une nouvelle trame de données où j'aurais les colonnes comme:

0,1,3,4,6,7,9,.....,n

J'ai essayé comme ça:

shape = df.shape[1]
for i in range(2,shape,3):
    df = df.drop(df.columns[i], axis=1) 

Mais j'obtiens une erreur indiquant que l'index est hors limite et je suppose que cela se produit parce que la forme du dataframe change lorsque je supprime les colonnes. si je ne stocke tout simplement pas la sortie de la boucle «for», alors le code fonctionne mais je ne reçois pas ma nouvelle trame de données.

Comment résoudre ce problème? Merci

0
Samiur Rahman 9 déc. 2020 à 15:27

3 réponses

Meilleure réponse

Le problème avec le code est , chaque fois que vous déposez une colonne dans votre boucle, vous vous retrouvez avec un ensemble de colonnes différent car vous écrasez le df après chaque itération. Lorsque vous essayez de supprimer la troisième colonne suivante de CE nouvel ensemble de colonnes, non seulement vous supprimez la mauvaise, vous finissez par manquer de colonnes. C'est pourquoi vous obtenez l'erreur que vous obtenez.

iter1 -> 0,1,3,4,5,6,7,8,9,10 ... n #first you drop 2 which is 3rd col
iter2 -> 0,1,3,4,5,7,8,9,10 ... n   #next you drop 6 which is 6th col (should be 5)
iter3 -> 0,1,3,4,5,7,8,9, ... n     #next you drop 10 which is 9th col (should be 8)

Ce que vous voulez faire, c'est calculer les index à l'avance, puis les supprimer en une seule fois.


Vous pouvez simplement obtenir les index des colonnes que vous souhaitez supprimer avec range, puis les supprimer.

drop_idx = list(range(2,df.shape[1],3)) #Indexes to drop
df2 = df.drop(drop_idx, axis=1)         #Drop them at once over axis=1


print('old columns->', list(df.columns))
print('idx to drop->', drop_idx)
print('new columns->',list(df2.columns))
old columns-> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
idx to drop-> [2, 5, 8]
new columns-> [0, 1, 3, 4, 6, 7, 9]
1
Akshay Sehgal 9 déc. 2020 à 15:28

Voici une solution avec une logique inversée - sélectionnez toutes les colonnes en supprimant chaque troisième colonne.

Vous pouvez filtrer les valeurs par comparaison ajoutée 1 au tableau d'assistance, avec 3 modulo comparer pour différent de 0 et passer à DataFrame.loc:

df = pd.DataFrame({
        'A':list('abcdef'),
         'B':[4,5,4,5,5,4],
         'C':[7,8,9,4,2,3],
         'D':[1,3,5,7,1,0],
         'E':[5,3,6,9,2,4],
         'F':list('aaabbb')
})

df = df.loc[:, (np.arange(len(df.columns)) + 1) % 3 != 0]
print (df)
   A  B  D  E
0  a  4  1  5
1  b  5  3  3
2  c  4  5  6
3  d  5  7  9
4  e  5  1  2
5  f  4  0  4
0
jezrael 9 déc. 2020 à 12:53

Vous pouvez utiliser la compréhension de liste pour filtrer les colonnes:

df = df[[k for k in df.columns if (k + 1) % 3 != 0]]

Si les noms sont différents (par exemple, des chaînes) et que vous souhaitez supprimer toutes les 3 colonnes, quel que soit leur nom, alors:

df = df[[k for i, k in enumerate(df.columns, 1) if i % 3 != 0]]
0
Pierre D 9 déc. 2020 à 12:33
65216773