Python中用encoding声明的文件编码和文件的实际编码之间的关系

部署运行你感兴趣的模型镜像

【背景】

python中的字符串编码,搞晕很多人,包括之前的我。

随着对于python的编码的深入了解,后来才算搞懂,关于python的,用encoding去声明的文件编码,和,python文件实际的编码,之间的关系。

 

Python中用encoding声明的文件编码和文件的实际编码之间的关系

1.解释声明的编码和真实的编码之前,需要了解,正常的情况下,python文件的话,如何声明文件的编码:

【整理】关于Python脚本开头两行的:#!/usr/bin/python和# -*- coding: utf-8 -*-的作用 – 指定文件编码类型

 

背景知识

1.不了解各种编码,尤其是常见的UTF-8,GBK等编码的,去看:

字符编码详解

2.不会对文件进行编码转换的,可以去用Notepad++的编码转换功能:

用Notepad++实现不同字符编码之间的转换

3.对于windows的cmd的默认是GBK编码不熟悉的,去看:

Windows的命令行工具: cmd

 

然后再来说,关于声明的编码,和文件本身的编码事情。

声明的编码和实际的编码匹配的时候:声明为UTF-8编码,文件实际编码也的确是UTF-8

(1)示例代码:

#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
-------------------------------------------------------------------------------
[Function]
【整理】Python中用encoding声明的文件编码和文件的实际编码之间的关系
http://www.crifan.com/python_string_encoding_declare_encoding_vs_file_real_encoding

[Date]
2013-07-19 

[Author]
Crifan Li

[Contact]
http://www.crifan.com/about/me/
-------------------------------------------------------------------------------
"""
 
#---------------------------------import---------------------------------------

#------------------------------------------------------------------------------
def declare_encoding_vs_real_encoding_declareUtf8RealUtf8():
    """
        Demo Python declare encoding vs. real file encoding
    """
    helpInfo = """在当前Python文件的第一行,用
    # -*- coding: utf-8 -*-
    去声明当前文件编码是utf-8
    所以,当前文件,也必须的确是UTF编码的。
    如此:
    1. Python解析器解析当前文件,才会去按照UTF-8解析
    2. 后面的,当前文件内的,直接写出的中文字符,自然也的确就是UTF-8
    3. 然后在用decode("utf-8")去解码,才能正确,详见后面代码的演示
    """;

    realUtf8Char = "我是UTF-8的中文字符串";
    decodedUnicodeStr = realUtf8Char.decode("utf-8");
    print "decodedUnicodeStr=",decodedUnicodeStr; #在windows的cmd中,此处Unicode字符串,才能正常输出:decodedUnicodeStr= 我是UTF-8的中文字符串
    

###############################################################################
if __name__=="__main__":
    declare_encoding_vs_real_encoding_declareUtf8RealUtf8();

(2)在Notepad++中,可以看出,当前文件我的确已经设置成了UTF-8:

declare encoding utf8 real is utf8

 

(3)代码下载(右键另存为):

declare_encoding_vs_real_encoding_declareUtf8RealUtf8.py

 

(4)运行效果如下:

both is utf8 match so output cn char ok

 

声明的编码和实际的编码不匹配的时候:声明为UTF-8,文件实际编码是(ANSI的)GBK

 

(1)示例代码:

#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
-------------------------------------------------------------------------------
[Function]
【整理】Python中用encoding声明的文件编码和文件的实际编码之间的关系
http://www.crifan.com/python_string_encoding_declare_encoding_vs_file_real_encoding

[Date]
2013-07-19 

[Author]
Crifan Li

[Contact]
http://www.crifan.com/about/me/
-------------------------------------------------------------------------------
"""
 
#---------------------------------import---------------------------------------

#------------------------------------------------------------------------------
def declare_encoding_vs_real_encoding_declareUtf8RealGBK():
    """
        Demo Python declare encoding vs. real file encoding
    """
    helpInfo = """在当前Python文件的第一行,用
    # -*- coding: utf-8 -*-
    去声明当前文件编码是utf-8
    而此处,故意,把当前文件的本身编码,转换为了GBK,即:声明的编码是UTF-8, 真正文件的编码是GBK -> 声明的编码,和真正文件编码,之间不一致 ->
    实际经过测试,由于本身文件编码是GBK的,虽然声明了UTF-8编码,但是Python解析器,实际上也会自动识别,并按照真正的GBK编码去解析,
    所以结果就是,当前文件,Python是按照,文件真实编码GBK去解码的。所以:
    后面的,当前Python文件出现的字符串,都是GBK的 ->
    对于GBK编码的字符串,去用GBK去decode,当时是正常的,可以得到Unicode的字符串的;
    对于GBK编码的字符串,用UTF-8去解码,当然会出错
    """;
    realEncodingGbkChar = "此处我实际上是GBK的中文字符串";
    useGbkDecodedUnicodeChar = realEncodingGbkChar.decode("gbk"); #此处可以正常获得Unicode字符串
    print "useGbkDecodedUnicodeChar=",useGbkDecodedUnicodeChar; #在Windows的cmd中输出Unicode字符串,可以正常输出:useGbkDecodedUnicodeChar= 此处我实际上是GBK的中文字符串
    useUtf8DecodedUnicodeChar = realEncodingGbkChar.decode("utf-8"); #此处就会报错:UnicodeDecodeError: 'utf8' codec can't decode byte 0xb4 in position 0: invalid start byte
    

###############################################################################
if __name__=="__main__":
    declare_encoding_vs_real_encoding_declareUtf8RealGBK();

(2)在Notepad++中,可以看出,当前文件我是故意,已经转换为GBK了:

declare utf8 real encoding is ansi gbk

(3)代码下载(右键另存为):

declare_encoding_vs_real_encoding_declareUtf8RealUtf8.py

 

(4)运行效果如下:

for real gbk str decode use utf8 will error

 

总结

可以看出:

虽然文件编码声明,即使和实际文件本身编码错误,Python解析器,也是识别真正的文件的编码的。

但是更明显,还是要尽量保持,python文件声明和实际上的文件本身的编码,一致,这样才不容易出问题。

 

原文链接:http://www.crifan.com/python_string_encoding_declare_encoding_vs_file_real_encoding/

 

想学人工智能(Python、数据分析、机器学习、深度学习、推荐系统、强化学习),来公众号AI派看看吧!!

 

您可能感兴趣的与本文相关的镜像

Python3.11

Python3.11

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

<think>好的,用户现在想用NumPy来读取CSV文件,之前我已经介绍了使用csv模块pandas的方法,但用户可能对性能有更高要求,或者需要处理数值型数据。我需要先回忆NumPy中相关的函数,比如genfromtxt或者loadtxt。 记得numpy.loadtxtnumpy.genfromtxt都可以用来读取文本文件,但genfromtxt功能更强大,可以处理缺失值。用户可能遇到数据中有缺失值的情况,所以需要说明如何处理。不过用户的问题是关于CSV,通常CSV中的分隔符是逗号,所以要指定delimiter参数。 用户可能已经知道pandas的read_csv,但想用NumPy直接得到数组,可能用于科学计算或机器学习任务,需要更高效的数据结构。需要指出两种方法的区别,比如genfromtxt可以自动处理数据类型,而loadtxt可能需要明确指定。 另外,用户可能需要处理标题行,但NumPy默认不会自动跳过标题,所以需要手动处理,比如用skip_header参数。或者使用usecols来选择特定列,这对大型文件有用。 还要考虑编码问题,虽然用户没提,但可能在示例中加入encoding参数。同时,示例代码需要展示如何读取数据后的操作,比如打印形状或部分数据,这样用户可以看到效果。 最后,要比较NumPy其他方法的优缺点,比如NumPy适合数值处理,但不擅长处理混合数据类型或文本,这时候可能需要用pandas。这样用户可以根据需求选择合适的方法。 需要确保示例代码正确,比如正确的函数名参数,比如delimiter=',',dtype=float等。同时,提醒用户处理可能的异常,比如文件不存在或格式错误。 可能用户之前的问题中提到过csv模块pandas,所以需要指出NumPy的适用场景,比如需要数组运算或与其它NumPy函数配合使用时更高效。此外,生成相关问题时要围绕NumPy的使用,比如处理缺失值、指定数据类型、读取大文件的分块处理等。</think>以下是使用NumPy读取CSV文件的详细方法与代码示例: --- ### 一、基础读取方法 #### 1. `np.loadtxt` 基础用法 ```python import numpy as np # 读取纯数值型CSV(无标题行) data = np.loadtxt('data.csv', delimiter=',', dtype=float) print("数据形状:", data.shape) print("首行数据:", data[0]) ``` *适用场景*:简单数值矩阵文件,默认跳过空行[^1] #### 2. `np.genfromtxt` 进阶用法 ```python # 处理含缺失值的CSV data = np.genfromtxt('data_with_nan.csv', delimiter=',', skip_header=1, # 跳过标题行 filling_values=np.nan, # 缺失值填充 dtype=np.float64) print("包含NaN的数据:\n", data) ``` *特点*:自动处理缺失值,支持复杂数据格式[^1] --- ### 二、混合数据类型处理 #### 1. 结构化数组 ```python # 定义数据类型(包含字符串数值) dtype = [('name', 'U10'), ('age', 'i4'), ('score', 'f4')] # 读取含文本列的CSV data = np.genfromtxt('mixed_data.csv', delimiter=',', skip_header=1, dtype=dtype, encoding='utf-8') print("结构化数组示例:", data['name'][:3]) # 访问name列前3个元素 ``` #### 2. 列选择与转换 ```python # 仅读取第2、4列(列索引从0开始) data = np.loadtxt('data.csv', delimiter=',', usecols=(1,3), converters={1: lambda x: float(x.strip('%'))/100}) # 转换百分比为小数 ``` --- ### 三、性能优化技巧 #### 1. 内存映射文件 ```python # 处理超大文件(不全部加载到内存) data = np.loadtxt('huge_data.csv', delimiter=',', dtype=np.float32, mmap_mode='r') # 内存映射模式 ``` #### 2. 预分配数组 ```python # 已知数据维度时提升性能 n_rows = 10000 n_cols = 5 preallocated = np.empty((n_rows, n_cols)) with open('data.csv') as f: for i, line in enumerate(f): preallocated[i] = np.fromstring(line, sep=',') ``` --- ### 四、方法对比 | 方法 | 优势 | 局限 | |-------------|-----------------------------|-------------------------| | `loadtxt` | 简单快速,适合规整数值数据 | 不支持自动类型推断 | | `genfromtxt` | 支持缺失值处理、类型转换 | 处理速度较慢 | | 结构化数组 | 可处理混合数据类型 | 字段访问不如pandas DataFrame直观 | | 内存映射 | 支持超大数据文件 | 需要手动管理内存 | --- ### 五、与pandas的协作 ```python import pandas as pd import numpy as np # 通过pandas预处理后转NumPy数组 df = pd.read_csv('complex_data.csv') matrix = df.select_dtypes(include=[np.number]).to_numpy() ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值