Actuellement, j'ai une base de données composée de colonnes avec des valeurs de 1 et de 0, j'aimerais parcourir les colonnes et supprimer celles qui ne contiennent que des 0. Voici ce que j'ai essayé jusqu'à présent:
ones = []
zeros = []
for year in years:
for i in range(0,599):
if year[str(i)].values.any() == 1:
ones.append(i)
if year[str(i)].values.all() == 0:
zeros.append(i)
for j in ones:
if j in zeros:
zeros.remove(j)
for q in zeros:
del year[str(q)]
En quelles années est une liste de trames de données pour les différentes années que j'analyse, les colonnes sont constituées de colonnes avec un et les zéros sont une liste de colonnes contenant tous les zéros. Existe-t-il un meilleur moyen de supprimer une colonne en fonction d'une condition? Pour une raison quelconque, je dois vérifier si ces colonnes sont également dans la liste des zéros et les supprimer de la liste des zéros pour obtenir une liste de toutes les colonnes zéro.
df.loc[:, (df != 0).any(axis=0)]
Voici un aperçu de la façon dont cela fonctionne:
In [74]: import pandas as pd
In [75]: df = pd.DataFrame([[1,0,0,0], [0,0,1,0]])
In [76]: df
Out[76]:
0 1 2 3
0 1 0 0 0
1 0 0 1 0
[2 rows x 4 columns]
df != 0
crée un DataFrame booléen qui est True, où df
est différent de zéro:
In [77]: df != 0
Out[77]:
0 1 2 3
0 True False False False
1 False False True False
[2 rows x 4 columns]
(df != 0).any(axis=0)
renvoie une série booléenne indiquant quelles colonnes ont des entrées non nulles. (L’opération any
agrège les valeurs de l’axe 0, c’est-à-dire des lignes, en une seule valeur booléenne. Le résultat est donc une valeur booléenne pour chaque colonne.)
In [78]: (df != 0).any(axis=0)
Out[78]:
0 True
1 False
2 True
3 False
dtype: bool
Et df.loc
peut être utilisé pour sélectionner ces colonnes:
In [79]: df.loc[:, (df != 0).any(axis=0)]
Out[79]:
0 2
0 1 0
1 0 1
[2 rows x 2 columns]
Pour "supprimer" les colonnes nuls, réaffectez df
:
df = df.loc[:, (df != 0).any(axis=0)]
Au cas où vous souhaiteriez un moyen plus expressif d'obtenir les noms de colonne zéro afin que vous puissiez les imprimer/les consigner et les supprimer, sur place, par leur noms :
zero_cols = [ col for col, is_zero in ((df == 0).sum() == df.shape[0]).items() if is_zero ]
df.drop(zero_cols, axis=1, inplace=True)
Certains tombent en panne:
# a pandas Series with {col: is_zero} items
# is_zero is True when the number of zero items in that column == num_all_rows
(df == 0).sum() == df.shape[0])
# a list comprehension of zero_col_names is built from the_series
[ col for col, is_zero in the_series.items() if is_zero ]