每当我读取使用toad导出的R(csv
)中的read.csv("file_name.csv")
文件时,第一列名称前面都会出现以下字符“ï.. ” 。此外,打开excel或notepad ++中的csv文件正确显示(没有前面的字符)。这是一个麻烦,因为我的解决方法是在每次读取后重命名该列。
感谢您解决此问题!
编辑:
通过右键单击查询的结果集并选择“快速导出 - >”,在Toad中创建导出。档案 - > CSV文件'
每条评论的更多细节:
head(readLines('test_file.csv'),n=3)
[1] "ID,LOCATION" "12021,1204" "12281,1204"
答案 0 :(得分:18)
试试这个:
d <- read.csv("test_file.csv", fileEncoding="UTF-8-BOM")
这适用于R 3.0.0+并删除文件中存在的BOM(对于从Microsoft应用程序生成的文件很常见:Excel,SQL server)
答案 1 :(得分:2)
随着用于数据科学的多语言内容的不断增长,再也没有一种安全的方法来假定utf-8(在我的情况下,excel假定使用UTF-16,因为我的大多数数据都包括繁体中文(普通话) ?)。
根据Microsoft Docs,Windows中使用了以下BOM:
|----------------------|-------------|-----------------------|
| Encoding | Bom | Python encoding kwarg |
|----------------------|-------------|-----------------------|
| UTF-8 | EF BB BF | 'utf-8' |
| UTF-16 big-endian | FE FF | 'utf-16-be' |
| UTF-16 little-endian | FF FE | 'utf-16-le' |
| UTF-32 big-endian | 00 00 FE FF | 'utf-32-be' |
| UTF-32 little-endian | FF FE 00 00 | 'utf-32-le' |
|----------------------|-------------|-----------------------|
我想出了以下方法,该方法似乎可以很好地使用文件开头的字节顺序标记检测编码:
def guess_encoding_from_bom(filename, default='utf-8'):
msboms = dict((bom['sig'], bom) for bom in (
{'name': 'UTF-8', 'sig': b'\xEF\xBB\xBF', 'encoding': 'utf-8'},
{'name': 'UTF-16 big-endian', 'sig': b'\xFE\xFF', 'encoding':
'utf-16-be'},
{'name': 'UTF-16 little-endian', 'sig': b'\xFF\xFE', 'encoding':
'utf-16-le'},
{'name': 'UTF-32 big-endian', 'sig': b'\x00\x00\xFE\xFF', 'encoding':
'utf-32-be'},
{'name': 'UTF-32 little-endian', 'sig': b'\xFF\xFE\x00\x00',
'encoding': 'utf-32-le'}))
with open(filename, 'rb') as f:
sig = f.read(4)
for sl in range(3, 0, -1):
if sig[0:sl] in msboms:
return msboms[sig[0:sl]]['encoding']
return default
# Example using python csv module
def excelcsvreader(path, delimiter=',',
doublequote=False, quotechar='"', dialect='excel',
escapechar='\\', fileEncoding='UTF-8'):
filepath = os.path.expanduser(path)
fileEncoding = guess_encoding_from_bom(filepath, default=fileEncoding)
if os.path.exists(filepath):
# ok let's open it and parse the data
with open(filepath, 'r', encoding=fileEncoding) as csvfile:
csvreader = csv.DictReader(csvfile, delimiter=delimiter,
doublequote=doublequote, quotechar=quotechar, dialect=dialect,
escapechar='\\')
for (rnum, row) in enumerate(csvreader):
yield (rnum, row)
我意识到,这需要打开文件才能读取两次(一次二进制,一次为编码文本),但是在这种特殊情况下,API确实很难做到这一点。
无论如何,我认为这比简单地假设utf-8健壮得多,并且显然自动编码检测无法正常工作...
答案 2 :(得分:1)
我知道这是一个非常老的问题,但是我发现最简单的解决方案是使用NotePad ++。在NotePad ++中打开CSV文件,单击“编码”,然后选择“以UTF-8编码”并保存文件。它将删除BOM表,并且原始代码应该可以工作。
答案 3 :(得分:0)
在进一步研究之后,它与BOM(字节顺序标记)添加的字符有关。显然不能使用快速导出,而是使用数据导出向导,因为它允许设置文件编码。它适用于我的设置为西欧(Windows)而不是unicode utf-8。