如何删除非法字符,以便数据框可以写入Excel

use*_*331 15 export-to-excel pandas

我正在尝试使用ExcelWriter将数据帧写入Excel电子表格,但它一直返回错误:

openpyxl.utils.exceptions.IllegalCharacterError
Run Code Online (Sandbox Code Playgroud)

我猜测ExcelWriter不喜欢的数据框中有一些字符.这看起来很奇怪,因为数据框是由三个Excel电子表格组成的,所以我看不出Excel会不会有这样的字符!

有没有办法迭代数据框并替换ExcelWriter不喜欢的字符?我甚至不介意它只是删除它们.

什么是从数据帧中删除或替换非法字符的最佳方法?

use*_*331 26

根据Haipeng Su的回答,我添加了一个功能:

dataframe = dataframe.applymap(lambda x: x.encode('unicode_escape').
                 decode('utf-8') if isinstance(x, str) else x)
Run Code Online (Sandbox Code Playgroud)

基本上,如果它们存在,它会逃脱unicode字符.它工作,我现在可以再次写入Excel电子表格!

  • 好吧....它可以工作,但是生成的文件内容类似于“\u4ee5\u4e0b\u6587\u9577...” (4认同)

Jia*_*Zou 11

尝试不同的excel编写器引擎解决了我的问题.

writer = pd.ExcelWriter('file.xlsx', engine='xlsxwriter')
Run Code Online (Sandbox Code Playgroud)


小智 9

我也遇到了同样的问题。我解决了如下问题:

  1. 安装python包xlsxwriter:
pip install xlsxwriter
Run Code Online (Sandbox Code Playgroud)
  1. 将默认引擎“ openpyxl”替换为“ xlsxwriter”:
dataframe.to_excel("file.xlsx", engine='xlsxwriter')
Run Code Online (Sandbox Code Playgroud)

  • 我认为这是一个强有力的竞争者应该接受的答案。 (2认同)

all*_*lee 9

如果您不想安装另一个 Excel 编写器引擎(例如 xlsxwriter),您可以尝试通过查找导致IllegalCharacterError错误发生的模式来删除这些非法字符。

打开cell.py/path/to/your/python/site-packages/openpyxl/cell/,查找check_string函数,您会看到它正在使用定义的正则表达式模式ILLEGAL_CHARACTERS_RE来查找那些非法字符。试图找到它的定义,你会看到这一行:

ILLEGAL_CHARACTERS_RE = re.compile(r'[\000-\010]|[\013-\014]|[\016-\037]')

这一行是您需要删除这些字符的内容。将此行复制到您的程序并在将数据框写入 Excel 之前执行以下代码:

dataframe = dataframe.applymap(lambda x: ILLEGAL_CHARACTERS_RE.sub(r'', x) if isinstance(x, str) else x)

上面的行将删除每个单元格中的那些字符。


但这些字符的起源可能是一个问题。正如您所说,数据框来自三个 Excel 电子表格。如果源 Excel 电子表格包含这些字符,您仍然会遇到这个问题。因此,如果您可以控制源电子表格的生成过程,请尝试从那里删除这些字符。

  • 很好的解决方案。您可以像“from openpyxl.cell.cell import ILLEGAL_CHARACTERS_RE”一样从 openpyxl 导入它,而不是重新定义“ILLEGAL_CHARACTERS_RE”。 (2认同)

Hai*_*gSu 5

当将数据帧写入html或csv时,我也在数据帧中处理一些奇怪的字符。例如,对于带有重音符号的字符,我无法写入html文件,因此我需要将这些字符转换为没有重音符号的字符。

我的方法可能不是最好的,但是它可以帮助我将unicode字符串转换为ascii兼容的字符串。

# install unidecode first 
from unidecode import unidecode

def FormatString(s):
if isinstance(s, unicode):
  try:
    s.encode('ascii')
    return s
  except:
    return unidecode(s)
else:
  return s

df2 = df1.applymap(FormatString) 
Run Code Online (Sandbox Code Playgroud)

在您的情况下,如果您只想通过更改return unidecode(s)为来消除非法字符return 'StringYouWantToReplace'

希望这可以给我一些解决您问题的想法。