Python 当某些字符串具有UTF-8字符时,使用DataFrame.style.render

Python 当某些字符串具有UTF-8字符时,使用DataFrame.style.render,python,pandas,dataframe,encoding,Python,Pandas,Dataframe,Encoding,使用dataframe.style时,重音字符会正确显示在Jupyter上: df = pandas.DataFrame([['Madrid', 'León']], index=['Spain'], columns=['BigCity', 'SmallCity']) df.style BigCity SmallCity Spain Madrid León 但是,如果使用style.render()方法获取HTML并将其写入文件,则重音字符的编码不正确: df.st

使用dataframe.style时,重音字符会正确显示在Jupyter上:

df = pandas.DataFrame([['Madrid', 'León']], index=['Spain'], columns=['BigCity', 'SmallCity'])
df.style    
        BigCity SmallCity
Spain   Madrid  León
但是,如果使用style.render()方法获取HTML并将其写入文件,则重音字符的编码不正确:

df.style.render()
'<style  type="text/css" >\n</style>  \n<table id="T_a3788466_eb00_11e8_8a82_88e9fe638ee6" > \n<thead>    <tr> \n        <th class="blank level0" ></th> \n        <th class="col_heading level0 col0" >BigCity</th> \n        <th class="col_heading level0 col1" >SmallCity</th> \n    </tr></thead> \n<tbody>    <tr> \n        <th id="T_a3788466_eb00_11e8_8a82_88e9fe638ee6level0_row0" class="row_heading level0 row0" >Spain</th> \n        <td id="T_a3788466_eb00_11e8_8a82_88e9fe638ee6row0_col0" class="data row0 col0" >Madrid</td> \n        <td id="T_a3788466_eb00_11e8_8a82_88e9fe638ee6row0_col1" class="data row0 col1" >León</td> \n    </tr></tbody> \n</table> '
df.style.render()
“\n\n\n\n\n大城市\n小城市\n\n\n西班牙\n马德里\n莱昂\n\n”
当然,这是行不通的。这是浏览器显示的内容:




如何纠正这一点

这里的问题不完全是HTML或Pandas问题,而是字符集问题。看

您的“带锐音符的小拉丁字母o”在UTF-8中是0xC3 0xB3。因此,第一个字节是195,第二个字节是179。看上面的链接,195是“带波浪号的拉丁文大写字母A”,而179是“上标三”。这就是为什么你会看到ó

所以熊猫正在生成正确的UTF-8HTML,但是没有人告诉浏览器。您可以将HTML字符集显式设置为UTF-8,也可以将HTML版本显式设置为5(默认为UTF-8,但可能存在特定于浏览器的问题)


另一种修复方法可能是从Pandas获取输出,并在写入文件之前调用
.encode('ISO-8859-1')
对其进行转换。这将把ó写成243,它应该在不更改HTML头的情况下工作。如果您的文档中包含ISO-8859-1以外的字符,那么这肯定无法正常工作,而将其保存在UTF-8中将支持所有字符。

我自己的问题的答案很简单,只需在render()方法的输出前加上如下标题:

outputHTML = '<meta charset="UTF-8">'+df.style.render()
outputHTML=''+df.style.render()

FWIW我仍然不明白为什么render()方法不会自动执行此操作。正如约翰指出的那样,网上可能有很多文档,但我一直无法找到解释

我认为这是HTML呈现的问题,而不是创建问题。我在我这边检查了你的代码,它运行得非常好。谢谢你@John。我的个人资料就是你所谓的公民数据科学家,对字符集知之甚少。诚然,我不知道什么是ISO-8859-1,也不知道如何在浏览器中设置HTML版本。使用的浏览器是Safari 12.0.1和Firefox 63.0.3。无论如何,您的解决方案适用于拉丁字符,但我也有中文字符:
UnicodeEncodeError:“latin-1”编解码器无法对280042-280057位置的字符进行编码:序号不在范围(256)
是否有一种方法可以抽象此问题?或者我必须花时间学习所有这些吗?对于无法编码为拉丁-1的汉字,您必须将HTML文档设置为HTML5或HTML字符集设置为UTF-8。其中任何一个都可以通过HTML标题来完成,因为在线上有大量的文档。