Pandas: расположение строки с ошибкой

Я новичок в Pandas и пытаюсь выяснить, где мой код ломается. Скажем, я делаю преобразование типа:

df['x']=df['x'].astype('int')

... и я получаю сообщение об ошибке "ValueError: неверный литерал для long() с базой 10: '1.0692e + 06'

В общем случае, если у меня есть 1000 записей в фреймворке данных, как я могу узнать, какая запись вызывает перерыв. Есть ли что-нибудь в ipdb для вывода текущего местоположения (т.е. Где код сломался)? В основном, я пытаюсь определить, какое значение не может быть преобразовано в Int.

Ответ 1

Ошибка, которую вы видите, может быть вызвана значением (-ами) в столбце x, являющимся строкой:

In [15]: df = pd.DataFrame({'x':['1.0692e+06']})
In [16]: df['x'].astype('int')
ValueError: invalid literal for long() with base 10: '1.0692e+06'

В идеале проблему можно избежать, убедившись, что значения, хранящиеся в DataFrame уже не являются строками при построении DataFrame. Как это сделать, конечно, зависит от того, как вы создаете DataFrame.

После того, как DataFrame можно было установить с помощью applymap:

import ast
df = df.applymap(ast.literal_eval).astype('int')

но вызов ast.literal_eval для каждого значения в DataFrame может быть медленным, поэтому наилучшим вариантом является устранение проблемы с самого начала.


Обычно вы можете отбрасывать в отладчик, когда возникает исключение, для проверки проблемного значения row.

Однако в этом случае исключение происходит внутри вызова astype, который представляет собой тонкую оболочку вокруг C-скомпилированного кода. Скомпилированный код выполняет цикл через значения в df['x'], поэтому отладчик Python здесь не помогает - он не позволит вам понять, какое значение вызывает исключение из C-скомпилированного кода.

Существует много важных частей Pandas и NumPy, написанных на C, С++, Cython или Fortran, а отладчик Python не будет принимать вас внутри тех фрагментов кода, которые не являются Python, где обрабатываются быстрые петли.

Поэтому вместо этого я вернусь к решению с низким бровь: перебираю значения в цикле Python и использую try...except, чтобы поймать первую ошибку:

df = pd.DataFrame({'x':['1.0692e+06']})
for i, item in enumerate(df['x']):
   try:
      int(item)
   except ValueError:
      print('ERROR at index {}: {!r}'.format(i, item))

дает

ERROR at index 0: '1.0692e+06'

Ответ 2

Чтобы сообщить о всех строках, которые не удалось отобразить из-за какого-либо исключения:

df.apply(my_function)  # throws various exceptions at unknown rows

# print Exceptions, index, and row content
for i, row in enumerate(df):
    try:
        my_function(row)
    except Exception as e: 
        print('Error at index {}: {!r}'.format(i, row))
        print(e)