如何检查CSV文件的编码

106

我有一个CSV文件,想要了解它的编码方式。在Microsoft Excel中是否有菜单选项可以帮助我检测它的编码方式?

或者我需要使用类似C#或PHP的编程语言来推断它的编码方式。


可能是http://superuser.com/questions/280603/how-to-set-character-encoding-when-opening-excel的重复问题。 - Gandhi
非常相关:如何确定文本文件的编码表 - wjandrea
11个回答

86

你可以使用Notepad++来评估文件的编码,无需编写代码。打开文件的评估编码将显示在底部栏的最右侧。支持的编码可以通过转到设置 -> 首选项 -> 新文档/默认目录并查看下拉菜单来查看。


21
哎?这是在使用chardet吗?感觉这个回答很差劲。 - mlissner
3
你是在问Windows内置文本编辑器记事本是否使用了Python(或者可能是JavaScript)库?我相信它没有,因为它是用本地编译语言如C++编写的。此外,文本编码是基于事实而非感觉的,所以如果你知道这个回答不好的原因,请提出来,但你的感受与讨论无关。 - CamW
3
问题在于:CSV格式没有一种方法来识别其字符编码,这个格式本身就没有。因此,打开CSV文件的任何程序都必须猜测用于创建该文件的编码方式。问题是,记事本如何实现这一点呢?Chardet是一个库,用于进行此操作,它基于浏览器的方式(我记得它最初是一个C程序)。如果记事本在猜测编码(而不是假设所有CSV都是'windows-1252'或类似),则它可能使用类似于chardet的东西。但是,它使用了什么呢?我们不知道。我不建议采用这种方法,因为它是一个黑盒子。 - mlissner
我再补充一点。Chardet(以及其他库)的工作原理是通过嗅探文件内容中特定编码常见的二进制模式来确定编码方式。如果您以编程方式执行此操作,则可以检查整个文件以查找这些类型的模式。如果您通过GUI执行此操作,则必须快速完成,并且几乎肯定会限制自己只能查看文件的前X个字节,这可能不包含该模式。因此...我建议为此目的使用库,它可以读取整个文件,而不是像记事本这样需要对用户进行性能优化的GUI。 - mlissner
1
OP特别要求不使用库的解决方案。是的,由于涉及到未知因素,它并不是一个完美的解决方案,但我们知道:1. 记事本在处理大文件时会变慢,因为它需要加载大量数据。2. 记事本非常成熟,由微软编写,所以它很可能能够很好地检测编码。总的来说,我认为这个解决方案已经足够好了,并且需要的努力最少。 - CamW
显示剩余3条评论

81
在Linux系统中,您可以使用file命令。它将给出正确的编码。
示例:
file blah.csv

输出:

blah.csv: ISO-8859 text, with very long lines

原问题大概是关于 Windows 系统的,尽管您的回答可能对 Linux 用户也有帮助? - rwp
3
注意:我认为它并不是非常可靠。我保存了一个普通的csv文件,并检查了十六进制代码,发现它是GB2312编码(我的系统默认编码)。但是文件结果是“ASCII-text”。然而,也许“ASCII-text”在这里代表了“系统默认”,超出了它原来的含义。 - Rick
1
@Rick。许多编码都是ASCII的超集。从阅读维基百科文章得知,仅包含ASCII字符的GB2312 / EUC-CN文本与ASCII无法区分。 - TRiG

69
如果你使用Python,只需使用print()函数来检查csv文件的编码。例如:
with open('file_name.csv') as f:
    print(f)

输出结果大致如下:

<_io.TextIOWrapper name='file_name.csv' mode='r' encoding='utf8'>

5
这是对问题的答案。谢谢。 - Rob S
11
注意:这可能并不总是正确的100%。我有一个CSV文件,可以正确地以utf-16打开,但是本答案中的方法返回cp1252。尝试使用Pandas CSV读取器以cp1252打开它会返回ParserError,因此某些地方可能出了问题。 - Mast
2
我同意@Mast的观点。 - Filippos Ser
2
这个答案似乎是错误的!它总是显示 cp1252,即使我可以在Notepad++中看到csv文件是utf-8格式。只有当使用 with open('file_name.csv', encoding='utf-8') as f: 时,它才会实际显示utf-8,这并不是很有帮助。 - Benji
2
这个答案完全是错误的。Python用于打开文件的编码不一定与文件中数据的编码相对应;Python只是使用平台的默认编码。在Linux和我认为Mac上,它是UTF-8,而在Windows上,它是CP1252,因此上面的评论说这总是返回cp1252。有关更多详细信息,请参见“open”文档 - wjandrea
显示剩余4条评论

22

你也可以使用Python的chardet库。

# install the chardet library
!pip install chardet

# import the chardet library
import chardet 

# use the detect method to find the encoding
# 'rb' means read in the file as binary
with open("test.csv", 'rb') as file:
    print(chardet.detect(file.read()))

11

使用 chardet https://github.com/chardet/chardet。(文档简短易懂)。

安装Python,然后通过pip安装chardet,在最后使用命令行命令。

我在GB2312下测试过,它非常准确。(请确保至少有几个字符,只有一个字符的样本很容易出错)。

file 不是可靠的工具,如下图所示:

enter image description here


实际上,chardetect(python-chardet软件包中附带的cli工具)比file更可靠,但是对于计算出一定程度的置信度的结果,它也可能需要更长的时间(特别是对于大文件)。 - Cyril Chaboisseau
如果这个过程太耗时,你可以对文件进行采样以获得一个不错的结果,例如通过执行“head -n 500 bigfile.csv > smallerfile.csv”来获取前500行作为样本。 - greggles

6

或者您可以在Python控制台或Jupyter Notebook中执行:

import csv
data = open("file.csv","r") 
data

您将看到有关数据对象的信息,如下所示:

<_io.TextIOWrapper name='arch.csv' mode='r' encoding='cp1250'>

如您所见,它包含编码信息。


5

CSV文件没有标头指示编码。

您只能通过以下方式猜测:

  • 创建文件的平台/应用程序
  • 文件中的字节

在2021年,表情符号被广泛使用,但许多导入工具无法导入它们。上面的答案中经常推荐使用chardet库,但该库不能很好地处理表情符号。

icecream = ''

import csv

with open('test.csv', 'w') as f:
    wf = csv.writer(f)
    wf.writerow(['ice cream', icecream])


import chardet
with open('test.csv', 'rb') as f:
    print(chardet.detect(f.read()))

{'encoding': 'Windows-1254', 'confidence': 0.3864823918622268, 'language': 'Turkish'}

读取文件时,如果使用了这种编码方式,可能会导致UnicodeDecodeError错误。
在Mac上的默认编码是UTF-8,虽然在此处明确指定了它,但实际上并不需要...但在Windows上可能需要。
with open('test.csv', 'r', encoding='utf-8') as f:
    print(f.read())

ice cream,
file 命令也检测到了这个。
file test.csv
test.csv: UTF-8 Unicode text, with CRLF line terminators

如果自动检测出现问题,在尝试使用 chardet 之前,请先尝试使用 UTF-8


2
在Python中,你可以尝试使用“try”语句来捕获和处理异常。
from encodings.aliases import aliases
alias_values = set(aliases.values())

for encoding in set(aliases.values()):
    try:
        df=pd.read_csv("test.csv", encoding=encoding)
        print('successful', encoding)
    except:
        pass

1

正如@3724913(Jitender Kumar)提到的那样,可以使用file命令(在Windows上的WSL中也适用),通过执行file --exclude encoding blah.csv命令并使用man file中提供的信息,我能够获得csv文件的编码信息,因为在我的系统上file blah.csv不会显示编码信息。


0
import pandas as pd
import chardet
def read_csv(path: str, size: float = 0.10) -> pd.DataFrame:
 """
 Reads a CSV file located at path and returns it as a Pandas DataFrame. If 
 nrows is provided, only the first nrows rows of the CSV file will be 
 read. Otherwise, all rows will be read.

 Args:
    path (str): The path to the CSV file.
    size (float): The fraction of the file to be used for detecting the 
    encoding. Defaults to 0.10.

 Returns:
    pd.DataFrame: The CSV file as a Pandas DataFrame.

 Raises:
    UnicodeError: If the encoding of the file cannot be detected with the 
    initial size, the function will retry with a larger size (increased by 
    0.20) until the encoding can be detected or an error is raised.
 """
 try:
    byte_size = int(os.path.getsize(path) * size)

    with open(path, "rb") as rawdata:
        result = chardet.detect(rawdata.read(byte_size))

    return pd.read_csv(path, encoding=result["encoding"])

 except UnicodeError:
    return read_csv(path=path, size=size + 0.20)

嗨,我刚刚添加了一个函数来找到正确的编码并读取给定文件路径中的CSV文件。觉得这可能会很有用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接