2016-05-28 2 views
0

Я использую drop(), чтобы очистить строки с значениями мусора (NaN, NaT, '') из определенных столбцов.pandas drop() - ошибка - метка [] не указана в оси

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 

Нарушитель строка:

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 

Что такое проблема здесь?

Я знаю, что альтернативный способ достижения моей цели состоит в том, чтобы нарезать строки, , но я хочу понять, что здесь происходит не так!

+0

Вы можете вместо этого проверить 'user_data_to_clean.loc [124]'? 'iloc' смотрит на позицию строки, а не на метку. Возможно, вы пытаетесь удалить строку, которая ранее была удалена. – ayhan

+0

@ayhan: Спасибо, оказывается, это была моя ошибка. Я уронил ряды, которые уже были сброшены. – gprakhar

ответ

2

IIUC вы можете использовать Векторизованных boolean indexing скорее drop с iterrows(), потому что iterrows() очень медленно: Для маски от NaN и NaT использования isnull:

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

Пример:

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 

Булева маска :

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

Теперь я использую метод boolean masking. iterrows работал очень медленно. Огромное спасибо. – gprakhar

2

я хотел бы сделать это таким образом:

тест 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 

очистить:

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 если вы хотите серьезный и надежный (но медленно) использование проверки электронной почты validate_email модуль вместо

если вам нужно email_count, сделайте это после очистки g up:

+0

Спасибо, я использую модуль validate_email. Он отлично работает. – gprakhar

Смежные вопросы