J'ai un pd.DataFrame
qui a été créé en analysant des feuilles de calcul Excel. Une colonne qui contient des cellules vides. Par exemple, ci-dessous se trouve la sortie pour la fréquence de cette colonne, 32320 enregistrements ont des valeurs manquantes pour Tenant .
>>> value_counts(Tenant, normalize=False)
32320
Thunderhead 8170
Big Data Others 5700
Cloud Cruiser 5700
Partnerpedia 5700
Comcast 5700
SDP 5700
Agora 5700
dtype: int64
J'essaie de supprimer les lignes où le locataire est manquant, mais l' .isnull()
option ne reconnaît pas les valeurs manquantes.
>>> df['Tenant'].isnull().sum()
0
La colonne a le type de données "Objet". Que se passe-t-il dans ce cas? Comment puis-je supprimer des enregistrements où le locataire est manquant?
np.nan
-vous quand vous pouvez le fairepd.np.nan
?df[df['Tenant'].astype(bool)]
(en supposant qu'il n'y ait pas de caractères d'espace blanc - chaîne vide uniquement) est plus rapide quedf.replace('', np.nan).dropna(subset=['Tenant'])
Pythonique + Pandorable:
df[df['col'].astype(bool)]
Les chaînes vides sont fausses, ce qui signifie que vous pouvez filtrer sur des valeurs booléennes comme ceci:
df = pd.DataFrame({ 'A': range(5), 'B': ['foo', '', 'bar', '', 'xyz'] }) df A B 0 0 foo 1 1 2 2 bar 3 3 4 4 xyz
df['B'].astype(bool) 0 True 1 False 2 True 3 False 4 True Name: B, dtype: bool df[df['B'].astype(bool)] A B 0 0 foo 2 2 bar 4 4 xyz
Si votre objectif est de supprimer non seulement les chaînes vides, mais également les chaînes contenant uniquement des espaces, utilisez
str.strip
au préalable:df[df['B'].str.strip().astype(bool)] A B 0 0 foo 2 2 bar 4 4 xyz
Plus rapide que vous ne le pensez
.astype
est une opération vectorisée, c'est plus rapide que toutes les options présentées jusqu'à présent. Au moins, d'après mes tests. YMMV.Voici une comparaison de temps, j'ai lancé d'autres méthodes auxquelles je pourrais penser.
Code d'analyse comparative, pour référence:
import pandas as pd import perfplot df1 = pd.DataFrame({ 'A': range(5), 'B': ['foo', '', 'bar', '', 'xyz'] }) perfplot.show( setup=lambda n: pd.concat([df1] * n, ignore_index=True), kernels=[ lambda df: df[df['B'].astype(bool)], lambda df: df[df['B'] != ''], lambda df: df[df['B'].replace('', np.nan).notna()], # optimized 1-col lambda df: df.replace({'B': {'': np.nan}}).dropna(subset=['B']), ], labels=['astype', "!= ''", "replace + notna", "replace + dropna", ], n_range=[2**k for k in range(1, 15)], xlabel='N', logx=True, logy=True, equality_check=pd.DataFrame.equals)
la source
value_counts omet NaN par défaut, vous avez donc probablement affaire à "".
Donc, vous pouvez simplement les filtrer comme
filter = df["Tenant"] != "" dfNew = df[filter]
la source
Il y a une situation où la cellule a un espace blanc, vous ne pouvez pas le voir, utilisez
df['col'].replace(' ', np.nan, inplace=True)
pour remplacer l'espace blanc par NaN, puis
df= df.dropna(subset=['col'])
la source
Vous pouvez utiliser cette variante:
import pandas as pd vals = { 'name' : ['n1', 'n2', 'n3', 'n4', 'n5', 'n6', 'n7'], 'gender' : ['m', 'f', 'f', 'f', 'f', 'c', 'c'], 'age' : [39, 12, 27, 13, 36, 29, 10], 'education' : ['ma', None, 'school', None, 'ba', None, None] } df_vals = pd.DataFrame(vals) #converting dict to dataframe
Cela produira (** - ne mettant en évidence que les lignes souhaitées):
age education gender name 0 39 ma m n1 ** 1 12 None f n2 2 27 school f n3 ** 3 13 None f n4 4 36 ba f n5 ** 5 29 None c n6 6 10 None c n7
Donc, pour supprimer tout ce qui n'a pas de valeur `` éducation '', utilisez le code ci-dessous:
df_vals = df_vals[~df_vals['education'].isnull()]
('~' indiquant NON)
Résultat:
age education gender name 0 39 ma m n1 2 27 school f n3 4 36 ba f n5
la source