панды.DataFrame.drop_duplicates() сбой с нехешируемым типом: ‘list’, как мне найти виновника

#python #pandas #dataframe

#python #pandas #dataframe

Вопрос:

При запуске df.drop_duplicates() Я получаю сообщение об ошибке TypeError: unhashable type: 'list' ; однако я не могу найти столбец-нарушитель.

Фрейм данных построен из json_normalize(), и есть один столбец, который является списком. Для этого столбца я запускаю df['col'] = df.col.apply(', '.join) , который, похоже, работает.

Когда я запускаю df.head() и df.tail() и даже просматриваю ~ 1000 записей, я все еще не могу найти какие-либо значения в форме [val1, val2, val3] . Даже один столбец, который изначально был списком, теперь val1, val2, val3 является.

Я также пробовал цикл for, перебирал имена столбцов и выполнял df.col.head(), и все же я не могу найти, где находится этот «список». У кого-нибудь есть какие-либо идеи о том, как легче найти столбец-нарушитель?

Комментарии:

1. Правильно, но dtypes, основываясь на моем опыте, не скажет вам, является ли содержимое указанного столбца списком или нет. Распространенными типами, которые я вижу из dtypes, являются object, int64, datetime64, где списки, я полагаю, обычно относятся к объектному типу.

2. @XavierBrt dtypes покажет объект для типов str или типов списков. Это неоднозначно. Лучше всего определить метод, который перебирает каждое отдельное значение df и проверяет, например, с помощью isinstance или type

3. Используйте что-то вроде df[df.applymap(type).eq(list).any(1)] . Это вернет подмножество строк, в которых хотя бы одна ячейка является списком, что должно помочь вам найти проблему. Конечно, applymap это очень медленно, но должно быть достаточно прилично для отладки на этом небольшом примере.

Ответ №1:

Простой, но ресурсоемкий способ — просто проверить наличие экземпляра списка для каждой ячейки в фрейме данных, определив очень простой метод

 def islist(x):
    return isinstance(x, list)
 

а затем применить его с помощью df.applymap(islist)

Ответ №2:

Хотя приведенный выше ответ может работать, в моем наборе данных я никогда не мог заставить его вернуться, ядро моего ноутбука jupyter продолжало сбоить. Однако мой коллега предложил следующее, которое сработало и близко к приведенному выше, использует только df.sample() и является однострочным.

 df.sample(100).applymap(lambda x: isinstance(x, list)).any(0)