2016-05-28 4 views
0

Ich benutze drop() um Zeilen mit Müllwerten (NaN, NaT, '') aus bestimmten Spalten zu löschen.pandas drop() - Fehler - Label [] nicht in Achse

for index, row in user_data_to_clean.iterrows():  
    if row.email != row.email or row.email == '' or row.email == ' ': 
     user_data_to_clean.drop(index, inplace=True) 
     email_count = email_count + 1 

--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-22-bb0cb6d83902> in <module>() 
    24 
    25   if row.email != row.email or row.email == '' or row.email == ' ': 
---> 26    user_data_to_clean.drop(index, inplace=True) 
    27    email_count = email_count + 1 
    28 

/home/eyebell/local_bin/janacare/virtenv/lib/python2.7/site-packages/pandas/core/generic.pyc in drop(self, labels, axis, level, inplace, errors) 
    1871     new_axis = axis.drop(labels, level=level, errors=errors) 
    1872    else: 
-> 1873     new_axis = axis.drop(labels, errors=errors) 
    1874    dropped = self.reindex(**{axis_name: new_axis}) 
    1875    try: 

/home/eyebell/local_bin/janacare/virtenv/lib/python2.7/site-packages/pandas/indexes/base.pyc in drop(self, labels, errors) 
    2964    if errors != 'ignore': 
    2965     raise ValueError('labels %s not contained in axis' % 
-> 2966         labels[mask]) 
    2967    indexer = indexer[~mask] 
    2968   return self.delete(indexer) 

ValueError: labels [124] not contained in axis 

Die betreffende Zeile ist:

print user_data_to_clean.iloc[124] 
user_id          656 
first_name       xxxxxxx.A 
last_name         NaN 
username        xxxxxxxx 
email       [email protected] 
phone_number       7123372613 
date_joined     2013-09-27 00:00:00 
first_login         NaT 
last_activity        NaT 
Name: 182, dtype: object 

Was ist das Problem hier?

Ich weiß, eine alternative Möglichkeit, mein Ziel zu erreichen, ist die Zeilen zu zerschneiden, , aber ich möchte verstehen, was hier falsch läuft!

+0

Können Sie 'user_data_to_clean.loc [124]' stattdessen überprüfen? "iloc" betrachtet die Position der Zeile, nicht das Label. Sie versuchen möglicherweise, eine Zeile zu löschen, die zuvor gelöscht wurde. – ayhan

+0

@ayhan: Danke, stellt sich heraus, dass das mein Fehler war. Ich ließ Reihen fallen, die bereits fallen gelassen worden waren. – gprakhar

Antwort

2

IIUC können Sie vektorisiert verwenden boolean indexing eher als drop mit iterrows(), weil iterrows() sehr langsam ist: Für Maske von NaN und NaT Verwendung isnull:

print (user_data_to_clean[(user_data_to_clean.email != '') & 
          (user_data_to_clean.email != ' ') & 
          (user_data_to_clean.email.notnull()) ]) 

Probe:

import pandas as pd 
import numpy as np 

user_data_to_clean = pd.DataFrame({'email':['','aa',' ', np.nan, 'dd'], 
        'a':[7,5,6,4,7], 
        'b':[7,8,9,1,2]}) 

print (user_data_to_clean) 
    a b email 
0 7 7  
1 5 8 aa 
2 6 9  
3 4 1 NaN 
4 7 2 dd 

Boolean Maske :

print ((user_data_to_clean.email != '') & 
     (user_data_to_clean.email != ' ') & 
     (user_data_to_clean.email.notnull())) 

0 False 
1  True 
2 False 
3 False 
4  True 
Name: email, dtype: bool 

print (user_data_to_clean[(user_data_to_clean.email != '') & 
          (user_data_to_clean.email != ' ') & 
          (user_data_to_clean.email.notnull()) ]) 

    a b email 
1 5 8 aa 
4 7 2 dd 
+0

Ich verwende jetzt die boolesche Maskierungsmethode. Iterrows arbeitete sehr langsam. Ich danke dir sehr. – gprakhar

2

ich würde es auf diese Weise tun:

Test DF:

In [43]: df = pd.DataFrame({'email':['[email protected]', '[email protected]',' ', np.nan, '[email protected]', '1', '[email protected]', '', np.nan], 'col': np.random.randint(0,100,9)}) 

In [44]: df 
Out[44]: 
    col   email 
0 89   [email protected] 
1 81 [email protected] 
2 82 
3 43   NaN 
4 71  [email protected] 
5 3    1 
6 48 [email protected] 
7 48 
8 71   NaN 

aufzuräumen:

In [53]: df = df[(df.email.notnull()) & (df.email.str.strip().str.len() > 5)] 

In [54]: df 
Out[54]: 
    col   email 
1 97 [email protected] 
4 77  [email protected] 
6 47 [email protected] 

PS, wenn Sie eine schwere und robuste wollen (aber langsam) E-Mail-Validierung Verwendung validate_email Modul stattdessen

Wenn Sie email_count benötigen, tun Sie dies nach dem Reinigen g up:

+0

Danke, ich benutze das validate_email Modul. Es funktioniert großartig. – gprakhar

Verwandte Themen