Как начать цикл для выбранного ряда 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
Класс лениво создает записи при поиске кодовых точек, поэтому обрабатываются только те кодовые точки, которые действительно присутствуют в ваших данных. Я бы по-прежнему держал экземпляр карты для повторного использования, если вам нужно использовать его более одного раза, кэш, который он создает, можно использовать таким образом.