Как начать цикл для выбранного ряда pandas.df?

При обработке pandas.df с помощью for. Я обычно сталкиваюсь с ошибками. Когда ошибка будет устранена, мне придется перезапустить цикл for в начале кадра данных. Как запустить цикл for с позиции ошибки, избавившись от повторного запуска? Например:

senti = []
for i in dfs['ssentence']:
   senti.append(get_baidu_senti(i))

В приведенном выше коде я пытаюсь выполнить анализ настроений через API и сохранить их в виде списка. Однако API-интерфейс используется только для ввода GBK, тогда как мои данные кодируются в UTF-8. Так что обычно встречаются такие ошибки:

UnicodeEncodeError: 'gbk' codec can't encode character '\u30fb' in position 14: illegal multibyte sequence

Поэтому мне нужно вручную удалить определенные элементы, такие как \u30fb, и перезапустить цикл for. В настоящее время список "senti" уже содержит так много данных, что я не хочу отказываться от них. Что я могу сделать, чтобы улучшить цикл for?

1 ответ

Решение

Если ваш API требует кодирования в GBK, просто кодируйте в этот кодек, используя обработчик ошибок, отличный от 'strict' (по умолчанию).

'ignore' удалит любые кодовые точки, которые не могут быть закодированы в GBK:

dfs['ssentence_encoded'] = dfs['ssentence'].str.encode('gbk', 'ignore')

Смотрите раздел Обработка ошибок в Python codecs документация

Если вам нужно передать строки, но только те строки, которые можно безопасно кодировать в GBK, то я бы создал карту перевода, подходящую для str.translate() метод:

class InvalidForEncodingMap(dict):
    def __init__(self, encoding):
        self._encoding = encoding
        self._negative = set()
    def __missing__(self, codepoint):
        if codepoint in self._negative:
            raise LookupError(codepoint)
        if chr(codepoint).encode(self._encoding, 'ignore'):
            # can be mapped, record as a negative and raise
            self._negative.add(codepoint)
            raise LookupError(codepoint)
        # map to None to remove
        self[codepoint] = None
        return None

only_gbk = InvalidForEncodingMap('gbk')
dfs['ssentence_gbk_safe'] = dfs['sentence'].str.translate(only_gbk)

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

Другие вопросы по тегам