2015-08-31 5 views
0

У меня есть набор данных столбца формы:Как улучшить производительность следующего кода в Python

'< 1 year' 
'10+ years' 
'6 years' 
etc 

мне нужно был его преобразовать в целое формата, то есть «< 1 год» -> 0, '10 + лет '-> 10, а записи типа «6 лет» -> 6 и т. Д. Есть 500 000 записей. Я написал следующий сценарий для его очистки:

temp = data.X11 
for i in range(len(temp)): 
    if ~is_nan(temp[i]): 
     if isinstance(temp[i], six.string_types): 
      b= temp[i].split(" ") 
      if len(b) == 3 and (b[0])=='<': 
       temp[i] = 0 
      elif len(b) == 2: 
       if b[0] == '10+': 
        temp[i] = 10 
       else: 
        temp[i] = int(b[0]) 
     else: 
      if isinstance(temp[i], float): 
       temp[i] = math.floor(temp[i]) 
      if isinstance(temp[i], int): 
       if temp[i] >= 10: 
        temp[i] = 10 
       elif temp[i] < 1 and temp[i] >= 0: 
        temp[i] = 0 
       elif temp[i] < 0: 
        temp[i] = -10 
       else: 
        pass 


    else: 
     temp[i] = -10 

Это работает. Но недостатком является то, что он ужасно медленный (потребовалось несколько часов для завершения). Мой вопрос заключается в том, как улучшить производительность этого кода.

Любой совет или помощь с фрагментом кода были бы оценены.

Благодаря

ответ

1

Я не уверен, что вы можете многое сделать здесь. Вы можете попытаться избежать доступа к temp[i], итерации значений темпа. Вы также можете добавлять новые значения в конце другого списка (быстро) вместо изменения значения в середине (не так быстро).

new_temp = list() 
for temp_i in data.X11: 
    if ~is_nan(temp_i): 
     if isinstance(temp_i, six.string_types): 
      b = temp_i.split(" ") 
      if len(b) == 3 and (b[0])=='<': 
       new_temp.append(0) 
      elif len(b) == 2: 
       if b[0] == '10+': 
        new_temp.append(10) 
       else: 
        new_temp.append(int(b[0])) 
     else: 
      if isinstance(temp_i, float): 
       new_temp.append(math.floor(temp_i)) 
      if isinstance(temp_i, int): 
       if temp_i >= 10: 
        new_temp.append(10) 
       elif temp_i < 1 and temp_i >= 0: 
        new_temp.append(0) 
       elif temp_i < 0: 
        new_temp.append(-10) 
    else: 
     new_temp.append(-10) 

string.split, вероятно, будет очень медленным.

Если возможно, вы также можете попробовать выполнить свой код с помощью pypy или переписать его для совместимости с cython.

+0

Спасибо за ваши комментарии @QuentinRoy – user62198

+0

Я попробую. Решение с dict (см. Ниже) также занимает много времени. – user62198

1

С пандами
Вы можете создать dictionnary, а затем сопоставить свой dataframe с ним

dico = {'< 1 year' :1,'10+ years' :10,'6 years' :6 } 
df['New_var'] = df.var1.map(dico) 

займет всего пару секунд

+0

Большое спасибо за ваши комментарии. Но я не уверен в «var1» во второй строке кода. Не могли бы вы вкратце объяснить? Еще раз спасибо – user62198

+0

Ничего, я думаю, что понял. Благодарю. – user62198

+0

Я пытаюсь это сделать сейчас, но, к сожалению, это долгое время. – user62198

1

Я думаю, что виновник этого line:

math.floor (temp [i])

Он возвращает float, который использует довольно много бит, чем стандартное целое число. Передача результата этой операции целому числу может повысить производительность.

Другое решение будет модернизировать до Python 3.x.x, как в этих версиях round, floor и поместить все возвращаемые целые числа.

+0

Спасибо за ваши комментарии @DrewB – user62198

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