Pandas.read_excel() 读取excel 详解 含代码 含测试数据集 随Pandas版本持续更新

关于Pandas版本: 本文基于 pandas2.2.0 编写。

关于本文内容更新: 随着pandas的stable版本更迭,本文持续更新,不断完善补充。

传送门: Pandas API参考目录

传送门: Pandas 版本更新及新特性

传送门: Pandas 由浅入深系列教程

Pandas.read_excel()

用于将 Excel 文件读入 pandas DataFrame。支持从本地文件系统或 URL 读取 xls、xlsx、xlsm、xlsb、odf、ods 和 odt 文件扩展名。支持读取单个工作表或工作表列表的选项。

语法:

pandas.read_excel(io, sheet_name=0, *, header=0, names=None, index_col=None, usecols=None, dtype=None, engine=None, converters=None, true_values=None, false_values=None, skiprows=None, nrows=None, na_values=None, keep_default_na=True, na_filter=True, verbose=False, parse_dates=False, date_parser=_NoDefault.no_default, date_format=None, thousands=None, decimal=‘.’, comment=None, skipfooter=0, storage_options=None, dtype_backend=_NoDefault.no_default, engine_kwargs=None)

返回值:

DataFrame 或 由DataFrame构成的字典。

  • 读取的是单个工作表,则返回DataFrame。
  • 读取了多个工作表,则返回由工作表名称为Key,由DataFrame对象构成的字典。

有关何时返回 DataFrames 字典的更多信息,请参阅sheet_name参数中的注释。

参数说明:

io 文件路径

  • io : str, bytes, ExcelFile, xlrd.Book, path object, or file-like object

    该参数用于指定Excel 文件的路径。

    io为第一个参数,没有默认值,也不能为空,完整的显示传参方法是:pd.read_excel(io='data/data.xlsx')

    根据Python的语法,第一个参数传参时可以不写。例如io参数的传递过程可以简写为:pd.read_excel('data/data.xlsx')

    io参数接受以下类型的传入:

    • str: 可以是字符串类型的本地文件的路径,也可以是http, ftp, s3类型的链接;

    • path object: 路径对象,任何os.PathLike对象;

    • file-like object: 类文件对象,任何具有read()方法的对象,比如由open创建对象,或由StringIO创建的对象。

弃用于 Pandas 2.1.0 : 直接传递字节字符串(byte strings)已被标记为弃用(deprecated)。

以前,你可能直接将字节字符串传递给pandas.read_excel函数,但这种用法现在已经被弃用。建议将字节字符串包装在BytesIO对象中,然后将该对象传递给read_excel函数。BytesIO是Python中的一个类,它允许你将字节数据视为文件对象,以便进行文件读取等操作。

sheet_name 指定工作表名称

  • sheet_name : str, int, list, or None, default 0

    该参数用于指定读取Excle文件的哪个或哪些工作表(sheet)的索引,默认为0: 读取第1个工作表作为DataFrame。

    sheet_name参数接受以下类型的传入:

    • str: 如果传递字符串,将解释为要读取的工作表的名称,例如"Sheet1" ;
    • int: 如果传递整数,表示工作表的索引位置。图表工作表不算作工作表位置;
    • list: 可以传入列表,指定多个工作表。列表可以是整数列表或字符串列表,也可以是混合型的列表。例如,\[0, 1, "Sheet5"\]将作为一个DataFrame字典加载第一个、第二个和名为"Sheet5"的工作表;
    • None: 如果指定为None,则将读取Excel文件中的所有工作表。

header 列名所在行

  • header : int, list of int, default 0

    该参数用于指定解析后的 DataFrame 的列标签(也有称为字段名、列名、表头、列索引的)所在行。默认为0,表示第1行内容作为列标签。

    header参数接受以下类型的传入:

    • int: 使用整数指定的行作为列标签(行数从0开始计算);
    • list of int: 整数列表,会将列表内指定的行,合并为多层索引MultiIndex

☝︎ 注意 : 默认会把Excel的第0行视为列标签,即使你不传递header参数,默认也会这么做!

names 定义列名

  • names : array-like, default None

    names 参数在 pandas.read_excel 函数中用于指定 DataFrame 的列名。它是一个类似数组的对象,通常是字符串列表,用于提供DataFrame中每列的名称。

    如果 Excel 文件包含标题行(即第一行包含列名),你可以省略 names 参数,函数会自动使用第一行作为列名。

    names参数支持以下类型的传入:

    • 类似数组对象: 任何类似数组的对象都可以被传入names参数,其中的元素会作为列标签。

⚠️ 注意 : 如果你想通过names参数指定列标签,需要注意header参数对数据的影响:

  • header参数默认会把第0行作为列标签,即使你不传递header参数,默认也会这么做!

  • names参数会覆盖header参数指定的内容。

所以:

  • 如果你希望依然保留第0行数据你需要 显式 指定 header=None,才可以使用names参数传递列标签。否则数据会被覆盖掉。

  • 如果你不希望保留第0行数据,可以直接传递names参数,但是一般不建议这么做。

index_col 指定行索引所在列

  • index_col : int, str, list of int, default None

    用于指定哪一列作为 DataFrame 的行标签(行索引)。不指定时会自动使用以0开始的自然索引。

    index_col参数可以接受以下类型的值:

    • int: 一个整数,表示要用作行标签的列的索引,索引从 0 开始(0-indexed)。

    • str: 一个字符串,表示要用作行标签的列的名称。

    • list of int: 一个整数列表,表示要合并成 MultiIndex 的多级行标签。如果传递整数列表,这些列的位置将被合并成多级行索引。

    • None: 默认为 None,自动使用以0开始的自然索引。

⚠️ 注意 :

  • 如果使用了 usecols 参数选择了数据的子集,index_col 将基于选择的子集进行设置。

  • 如果在读取 Excel 数据时存在缺失值,并且 to_excel 函数的参数 merged_cells 被设置为 True,那么为了支持在写回 Excel 时保留合并单元格信息,缺失的值将会被前向填充(用前面的非缺失值进行填充)。如果想要避免前向填充缺失值,可以在读取数据后使用 set_index 方法来设置行标签,而不是在读取时通过 index_col 参数。

usecols 读取部分列

  • usecols : str, list-like, or callable, default None

    如果只想解析数据的部分列,可以用usecols来指定,这样可以加快加载速度并降低内存消耗。

    usecols参数可以接受以下类型的值:

    • None: 如果设置为 None,则解析所有列。
    • str: 一个逗号分隔的字符串,内容是 Excel 列标 的范围(例如,“A:E” 或 “A,C,E:F”)。范围包含两端。
    • list of int: 一个整数列表,表示要解析的列的索引(0-indexed)。
    • list of string: 一个字符串列表,表示要解析的列的名称。
    • callable: 一个可调用对象,用于对每个列名进行评估,如果可调用对象返回 True,则解析该列。

skiprows 跳过指定行(行数、或指定跳过规则)

  • skiprows : list-like, int, or callable, optional

    用于指定读取Excel文件时,跳过指定的行。可以是1行也可以是多行。

    skiprows参数可以接受以下类型的值:

    • list-like: 如果是一个列表,表示要跳过的行的 行号 ,行号从0开始。
    • int: 如果是整数,表示要跳过的 行数 (从第0行开始跳过)。
    • callable: 如果是可调用对象,该可调用对象将对行索引进行评估,如果返回 True,则跳过该行,否则不跳过。例如,lambda x: x in [0, 2] 表示跳过索引为 0 和 2 的行。

注意:

⚠️ 注意 : 使用 callable 跳行,skiprows 参数会逐个将Excel的行号 逐一传递callable 处理,在编写函数时,应留意返回值只能是 TrueFalse

nrows 从开头跳过指定行数

  • nrows : int, default None

    指定要解析的行数(前多少行)。它限制了读取文件时的行数,从而可以在读取大型文件时只读取文件的部分内容。

    nrows参数可以接受以下类型的值:

    • int: 整数,表示只读取Excel文件的前多少行。

skipfooter 从尾部跳过指定行数

  • skipfooter : int, default 0
    skipfooter 参数用于从文件尾部跳过指定行数,用法与 skiprows 参数一致,只不过是从文件最后面算。

    skipfooter参数可以接受以下类型的值:

    • int: 用于指定跳过多少行的整数。

dtype 数据类型转换

  • dtype : Type name or dict of column -> type, default None

    该参数用于指定数据或列的数据类型。

    dtype参数可以接受以下类型的值:

    • None: 默认为None,自动推断数据类型。
    • Type name: 单一的数据类型对象
    • dict of column -> type 数据类型字典,key是列标签,值是数据类型对象。表示指定的列使用指定的数据类型。没有被指定的列会自动推断。

⚠️ 注意 :

  • dtype 参数传递了单一的数据类型,解析Excel时,如果某列内容无法转换到目标数据类型,会引发ValueError错误。

  • 如果同时指定了 converters 参数,并且两者都对同一个列有了转换操作,那么在数据加载时,针对于这一列, dtype 参数的转换不会生效。

  • 如果同时指定了 converters 参数,两者所针对的不同的列,会分别生效。

convertes 数据类型转换、数据格式转换

  • converters : dict, default None

    converters 参数用于指定在某些列中转换值的函数字典。字典的键可以是整数或列标签,而值是转换方法 callable

    具体而言,converters 参数允许你为特定列指定自定义的值转换函数。可以是格式上的转换,也可以是数据类型的转换,非常灵活。

    这在需要对特定列的数据进行定制化的处理时非常有用,例如将特定格式的字符串转换为日期对象或进行其他定制化的数据清洗操作。

    converters 参数可以接受以下类型的值:

    • dict: 用于传递转换方法的字典,字典的键可以是整数(列的数字索引)或列标签,值是转换方法callable

⚠️ 注意 :

  • 使用 converters 参数进行数据转换,如果同时指定了 dtype 参数,并且两者都对同一个列有了转换操作,那么在数据加载时,针对于这一列, dtype 参数的转换不会生效。并且会报出提示。(只是有个提示,不会影响程序运行)

  • 使用 converters 参数进行数据转换,如果同时指定了 dtype 参数,两者所针对的不同的列,会分别生效。

engine 指定引擎

  • engine : str, default None

    enginestr 参数用于指定读取 Excel 文件的引擎。这个参数是可选的,如果没有指定,pandas 将尝试根据文件扩展名自动推断使用的引擎。

    enginestr参数可以接受以下类型的值:

    • “xlrd”: 该引擎支持旧式的 Excel 文件,扩展名为 .xls。

    • “openpyxl”: 该引擎支持较新的 Excel 文件格式,包括 .xlsx、.xlsm 等。

    • “odf”: 该引擎支持 OpenDocument 文件格式,扩展名为 .odf、.ods 和 .odt。

    • “pyxlsb”: 该引擎支持二进制 Excel 文件。

📌 改动于 Pandas 1.2.0 : xlrd 引擎现在仅支持旧式的 .xls 文件。当 engine=None 时,将使用以下逻辑来确定使用的引擎:

  • 如果 path_or_bufferOpenDocument 格式(.odf、.ods、.odt),则将使用 odf 引擎。

  • 如果 path_or_bufferxls 格式,将使用 xlrd 引擎。

  • 如果 path_or_bufferxlsb 格式,将使用 pyxlsb 引擎。

新增于 Pandas 1.3.0 : 于Pandas 1.3.0版本,增加了下面的逻辑。

  • 如果未被以上任何一种引擎识别,将使用openpyxl引擎。

true_values 真值识别

  • true_values : list, default None

    用于指定哪些值可以被转换为 boolean类型的 True,可以传入列表,指定多个值。

    true_values参数可以接受以下类型的值:

    • None: 默认值,只有True会被识别为boolean类型 的 True
    • list: 列表,支持以列表的形式传入多个值,将根据这些值,自动识别读取到的数据,并 尝试 转换为boolean类型 的 True

    true_values 参数一般会和 false_values 同时使用以达到如下目的:

    • 若整列内容,都可以被true_values 参数和 false_values 参数指定的值识别,会自动全部转换为TrueFalse

    • 若整列内容,都被转换为TrueFalse 这一列的数据类型会自动转换为 bool 类型。

⚠️ 注意 : 数字类型的值不会被转换,即便整列数字都可以被true_values 参数和 false_values 识别。数字类型的值的表现形式、数据类型都不会变。

false_values 假值识别

  • false_values : list, default None

    用于指定哪些值可以被转换为 boolean 类型的 False ,可以传入列表,指定多个值。

    false_values参数可以接受以下类型的值:

    • None: 默认值,只有False会被识别为boolean类型 的 False
    • list: 列表,支持以列表的形式传入多个值,将根据这些值,自动识别读取到的数据,并 尝试 转换为boolean类型 的 False

    false_values 参数一般会和 true_values 同时使用以达到如下目的:

    • 若整列内容,都可以被true_values 参数和 false_values 参数指定的值识别,会自动全部转换为TrueFalse

    • 若整列内容,都被转换为TrueFalse 这一列的数据类型会自动转换为 bool 类型。

⚠️ 注意 : 数字类型的值不会被转换,即便整列数字都可以被true_values 参数和 false_values 识别。数字类型的值的表现形式、数据类型都不会变

na_filter 是否检查缺失值的开关

  • na_filter : bool, default True

    用于控制是否检查缺失值,默认为 True

    keep_default_na参数可以接受以下类型的值:

    • bool: 布尔值,TrueFalse,默认为 Trueread_excel 会根据默认的缺失值类型检查缺失内容。如果为 False ,则 keep_default_nana_values 参数均无效。

na_values 自定义缺失值识别的字符

  • na_values : scalar, str, list-like, or dict, default None

    用于指定在读取数据时应该被解释为缺失值(NA/NaN)的字符串。

    na_values可以接受以下类型的值:

    • 标量(Scalar): 单个字符串或数字,表示需要识别为缺失值的特定值(数字的整形和浮点型不会区分,5和5.0是相同的)。
    • 字符串(String): 一个字符串,如果在数据中出现,就会被解释为缺失值。
    • 列表或类数组(List-like): 一个包含多个字符串或数字的列表,表示多个可能的缺失值。
    • 字典(Dictionary): 一个字典,用于指定每一列应该被解释为缺失值的具体值。字典的键是列名(或列的位置),值是相应列上的缺失值。

keep_default_na 是否保留默认的缺失值识别项

  • keep_default_na : bool, default True

    用于控制是否使用系统的默认缺失值,默认为True。

    keep_default_na参数可以接受以下类型的值:

    • bool: 布尔值,TrueFalse 默认为 Trueread_excel 会使用默认值识别缺失的内容。


    默认状态下,以下值会被认定为缺失值:

    ‘’, ‘#N/A’, ‘#N/A N/A’, ‘#NA’, ‘-1.#IND’, ‘-1.#QNAN’, ‘-NaN’, ‘-nan’, ‘1.#IND’, ‘1.#QNAN’, ‘<NA>’, ‘N/A’, ‘NA’, ‘NULL’, ‘NaN’, ‘None’, ‘n/a’, ‘nan’, ‘null’

⚠️ 注意 : 需要留意 na_values 参数和 keep_default_na 参数的相互影响:

keep_default_na

na_values

影响

True

指定

na_values的配置附加处理

True

未指定

使用默认缺失值

False

指定

使用na_values的配置

False

未指定

不处理缺失值
等同于na_filter=False

verbose 解析文件时,后台详细信息输出

  • verbose : bool, default False

    verbose参数用于控制读取Excel文件时的详细输出。这些信息包括加载文件的进度、数据类型推断、列名解析等。

    通过使用verbose参数,您可以获得有关CSV文件读取过程的更多信息,从而更好地了解正在执行的操作以及潜在的问题。这对于处理大型CSV文件或需要对数据进行特定操作时非常有用。

    建议使用该参数时,结合调试的断点功能,效果更佳。

    verbose参数可以接受以下类型的值:

    • bool: 布尔值,TrueFalse,默认为 False 。如果为 True ,读取文件时会输出更多的信息。即便不用print() 输出信息,也会有读取时的详情被输出。

parse_dates 解析或构建日期

  • parse_dates : bool, list-like, or dict, default False

    parse_dates 参数用于指定是否尝试解析或构建日期格式,并将其转换为datetime64[ns]数据类型,根据传入值的不同,其作用也不同:

    • bool: 如果为True,将尝试将索引列、列,解析为日期时间类型datetime64[ns]
    • 一维列表: 例如 [0, 2, 3]或[‘成交日期’, ‘订单日期’],则尝试将这些列分别解析为 datetime64[ns]
    • 二维列表: 例如 [[1, 3]]或 [[‘成交日期’, ‘订单日期’]] 则尝试将列这些列组合并解析为单个 datetime64[ns] 日期列。(原来的列会被删除)
    • dict: 字典,例如 {‘new_date’: [1, 3]}或 {‘new_date’: [‘成交日期’, ‘订单日期’]},则尝试将这些列组合并解析为单个 datetime64[ns] 日期列。并将结果命名为 ‘new_date’。(原来的列会被删除)

⚠️ 注意 :

Excel里面的 2023/1/5 20:02:22 这种日期时间格式,无法被 parse_dates 解析,请在读取文件后使用 pd.to_datetime 处理。否则会报错,请自行尝试。

如果某一列或索引包含无法解析的日期,整个列或索引将不被更改,作 object 据类型返回。

如果不想将某些单元格解析为 datetime64[ns] ,可以在 Excel 中将它们的类型更改为 “Text”。 这意味文本类型的日期时间,不会被 pd.read_excel 自动解析为 datetime64[ns] 的数据类型。

对于非标准的日期时间解析,可以在使用 pd.read_excel 后使用 pd.to_datetime 处理。>

需要注意的是,对于 ISO 8601T 格式的日期,存在一个快速解析的路径。

date_format 日期时间格式声明

  • date_format : str or dict of column -> format, default None

    date_format 用于指定日期的格式,它可以是一个字符串,也可以是一个字典,用于指定每列日期的格式。date_format 参数是在解析日期时 parse_dates 一起使用 的,不能单独使用!

    date_format 相当于是 parse_dates 参数的解释器,把日期时间的具体格式信息传递给 parse_dates 可以提升日期解析效率,这对大文件处理速度的提高有很大帮助。

    date_format 参数可以接受以下类型的值:

    • str: 符合 ISO8601格式化字符串

    • dict: 字典 字典的键是列标签或列的数字索引,字典的值是ISO8601标准的格式化字符串。

新增于 Pandas 2.0.0 : date_format 参数,新增于Pandas 2.0.0 版本。

date_parser 日期时间格式告知(已弃用)

  • date_parser : functionT, optional

    date_parser参数是一个可选参数,它一般作为 parse_dates 参数的辅助参数,即便你没有显式T启用 date_parser 参数,它也会在后台工作。

    date_parser 有两种工作状态:‘默认’和‘使用函数’:

    • 默认: 即参数未显式T使用的状态下, 使用 dateutil.parser.parser 来执行转换。date_parser 函数会以三种不同的方式尝试调用,按照以下顺序进行,如果发生异常则尝试下一种方式:

      • 将一个或多个数组(由 parse_dates 定义,这取决于你传递给parse_dates参数的是什么样的数据,bool,一维列表,二维列表,或是字典)作为参数传递给函数。
      • 将由 parse_dates 定义的列中的字符串值沿行方向连接成一个数组,并将其作为参数传递给函数。
      • 对每一行使用由 parse_dates 定义的列中的一个或多个字符串作为参数,分别调用 date_parser 函数。


      这样的设计允许 date_parser 处理多种不同的情况,以确保在解析日期时的灵活性。

    • function: 如果你显式T启用date_parser参数,并传递了函数,则使用你指定的函数处理日期时间。在函数运行的过程中,由date_parser传递给函数的原始数据到底是1个,还是多个数组,取决于你传递给 parse_dates 的数据类型。

Pandas 2.0.0 弃用 : 自Pandas 2.0.0版本开始,date_parser 已经被标记为弃用,将在未来版本中移除。

可以使用 date_format 参数替代;

或在读取文件后,使用 to_datetime() 函数进行日期时间格式的转换。

thousands 千分符识别

  • thousands : str, default None

    一般情况下, read_excel 会自动识别 数字的数据类型,但是请注意以下特殊情况:

    • 标准千分符: 含有标准千分符的数字,在Excel里,如果是以 文本格式 存储,则无法正确识别。
    • 非标准千分符: 含有非标准千分符的数字,在Excel里,无论以任何形式存储,都无法正确识别。


    如果想要这样的数据被识别为数字类型,就需要使用 thousands 参数指定千分符具体是什么字符,以便数据可以被正确解析为数字。并且读取后的数据,这个被识别的符号,会被清理掉,使数据更具可读性。

    thousands 参数可以接受以下类型的值:

    • str: 一个用于表示哪个字符应该被识别为千分符。

⚠️ 注意 : 只有当 含有 非标准千分符 的数字 在Excel文件里被存储为 文本格式 时,此参数才是必须的。

decimal 小数点识别

  • decimal : str, default ‘.’

    一般情况下, read_excel 会自动识别数字类型的数据,但是请注意以下特殊情况:

    • 标准小数点: 含有标准小数点的数字,在Excel里,无论以 任何格式 存储,都可以识别为数字。
    • 非标准小数点: 含有非标准小数点的数字,在Excel里,无论以 任何格式 存储,都无法识别为数字。

    如果希望含有 非标准小数点 的数据被识别为数字类型,则需要使用 decimal 参数指定小数点具体是什么字符,以便数据可以被正确解析为数字。

    decimal 参数可以接受以下类型的值:

    • str: 一个用于表示哪个字符应该被识别为小数点的字符串的字符串。

⚠️ 注意 : 只有当 含有 非标准小数点 的数字 在Excel文件里被存储为 文本格式 时,此参数才是必须的。

新增于 Pandas 1.4.0 : decimal 参数,新增于 Pandas 2.1.0 版本。

comment 注释符识别

  • comment : str, default None

    comment参数用于识别注释符,含有注释符的数据会被忽略。关于comment参数的使用,有如下需要注意的地方:

    • 当注释符出现在第0列 comment 参数 会忽略从注释符开始,一直到行尾的所有数据,这就意味着如果注释符出现在第0列的某个单元格,那么后面所有列的本行数据都会被忽略。
    • 当注释符出现在其他列 注释符前面的本行数据会保留,注释符后面的本行数据会被忽略。


    comment参数可以接受以下类型的值:

    • str: 用于描述注释符是什么,可以是由多个字符组成的字符串。

storage_options URL标头补充信息

  • storage_options : dict, optional

    storage_options参数一般作为当 io 参数是URL时的补充,适用于特定存储连接的额外选项,例如主机、端口、用户名、密码等。storage_options 参数接受字典类型的传入值。

    • 对于 HTTP(S) URL,字典的键值对将作为标头选项转发到 urllib.request.Request
    • 对于其他 URL(例如以“s3://”和“gcs://”开头的 URL),字典的键值对将转发到 fsspec.open。有关更多详细信息,请参阅 fsspecurllib

    storage_options参数可以接受以下类型的值:

    • dict 用于描述补充信息的字典,字典的键是自定义标头,字典的key是值。比如{“User-Name”: “tom”}

新增于 Pandas 1.2.0 : storage_options 参数,新增于Pandas 1.2.0 版本。

dtype_backend DataFrame后端引擎

  • dtype_backend : {‘numpy_nullable’, ‘pyarrow’}, default ‘numpy_nullable’

    dtype_backend参数用于指定生成 DataFrame 的后端引擎。目前尚处于实验阶段。随时可能会有变动,当版本稳定后会出一个关于 pyarrow 的专题文章。

    dtype_backend参数可以接受以下类型的值:

    • “numpy_nullable”: 返回支持可空数据类型的 DataFrame (默认值)。
    • “pyarrow”: 返回由 pyarrow 支持的可空 ArrowDtype DataFrame。

新增于 Pandas 2.0 : dtype_backend 参数,新增于Pandas 2.0 版本。

示例:

测试文件下载:

本文所涉及的测试文件,如有需要,可在文章顶部的绑定资源处下载。

若发现文件无法下载,应该是资源包有内容更新,正在审核,请稍后再试。或站内私信作者索要。

测试文件下载位置.png


示例:自Pandas 2.1.0 开始,字节型字符串,应包装在BytesIO对象中

# 例如,你之前的代码可能是这样的:
data = b'your_byte_data_here'
df = pd.read_excel(data, sheet_name='Sheet1'

# 现在你应该这样做:)from io import BytesIO

data = b'your_byte_data_here'
data_as_file = BytesIO(data)
df = pd.read_excel(data_as_file, sheet_name='Sheet1')



示例: sheet_name参数,传入列表会返回字典。其中字典的key,是列表里传入的整数或字符串内容,值是读取到的excel工作表里的内容。使用列表\[0, 1, "Sheet5"\]传递给sheet_name参数:

import pandas as pd

df = pd.read_excel(r'团队成员季度销售额.xlsx', sheet_name=[0, 1, 'Sheet4'])

# 观察df的对象类型:
print('df的数据类型是:', df)

# 遍历字典df的值,就可以观察所有读到的数据:
for i in df.values():
    print(i, '\n')

运行结果:
例图1 传入列表会返回字典



示例:使用names参数传递列名,header参数的行为参考

1、默认状态下 header 参数 会把第 0 列视为列标签,即便不显示传递header 参数:

import pandas as pd

df = pd.read_excel(r'团队成员季度销售额.xlsx')

# 观察读取结果
print('运行结果:\n')
print(df.head(2))
运行结果:
姓名片区1季度2季度3季度4季度
0左院梅华南1491108350009461
1左艳艳华南1106576234392359

如上面结果所示,即便没有传递 header 参数,Excel文件里的第0行数据,依然被用作 DataFrame 的列标签,因为这是header 参数的默认行为。

2、传递 names 参数,原有的列标签会被覆盖

import pandas as pd

df = pd.read_excel(r'团队成员季度销售额.xlsx', names=['q1', 'q2', 'q3', 'q4'])

# 观察读取结果
print('运行结果:\n')
print(df.head(2))
运行结果:
q1q2q3q4
左院梅华南1491108350009461
左艳艳华南1106576234392359

如上面结果所示,在没显式指定 header=None 的情况下,使用names 参数指定新的列标签,Excel文件里的第0行数据,会被覆盖掉。

3、如果希望原来的第0行数据可以保留,需要显式指定header=None

import pandas as pd

df = pd.read_excel(r'团队成员季度销售额.xlsx', header=None,
                   names=['q1', 'q2', 'q3', 'q4'])
# 观察读取结果
print('运行结果:\n')
print(df.head(2))
运行结果:
q1q2q3q4
姓名片区1季度2季度3季度4季度
左院梅华南1491108350009461

由上面的结果可以发现,显式指定 header=None 后,再使用names 参数指定新的列标签,原来的第0行数据被保留了下来(如上结果第1行数据)



示例:usecols参数传入字符串

1、如果传入字符串,只能使用Excel原始的 列标 范围:

import pandas as pd

df = pd.read_excel(r'团队成员季度销售额.xlsx', usecols='a:c')

# 多个列字母用逗号分割
# df = pd.read_excel(r'E:\Project\Pandas学习笔记\附件\数据集\团队成员季度销售额.xlsx',usecols='a,b,e')
# 列字母,列字母范围可以混合使用
# df = pd.read_excel(r'E:\Project\Pandas学习笔记\附件\数据集\团队成员季度销售额.xlsx',usecols='a,b,c:e')

print('运行结果:\n')
print(df.head(2))
运行结果:
姓名片区1季度
0左院梅华南1491
1左艳艳华南1106


示例:usecols参数使用callable

如果想要实现更复杂的部分数据选择功能,可以使用callable对象处理。假设,我们只想解析列名包含数字的列,可以这样做:

import pandas as pd  # 引入pandas
import re  # 引入re库,用于正则查找数字


# 第1步,构造一个用于筛选列名的函数
def number_in_columns(colunms_names):
    """用于筛选列名的函数"""
    result = []
    for i in colunms_names:
        if re.search(r'\d', i):  # 判断列名是否包含数字
            result.append(i)  # 符合要求,则加入结果集
    return result


# 第2步,从文件里先把列名读出来,可以只读取10行数据,加快读取速度
col_names = pd.read_excel(r'团队成员季度销售额.xlsx', nrows=10).columns

# 第3步,正式读取文件,并使用函数筛选想留下的列名
df = pd.read_excel(r'团队成员季度销售额.xlsx', usecols=number_in_columns(col_names))

# 输出前5行结果
print('运行结果:\n')
print(df.head(2))
运行结果:
1季度2季度3季度4季度
01491108350009461
11106576234392359


示例:dtype参数传入单个数据类型对象,会将所有内容转换为目标数据类型:

1、先看一下原始数据类型:

import pandas as pd

df = pd.read_excel(r'团队成员季度销售额.xlsx')

原始数据类型:

print(df.dtypes)

姓名 object
片区 object
1季度 int64
2季度 int64
3季度 int64
4季度 int64
dtype: object

2、使用dtype参数转换数据类型,只传递一个字符串:

import pandas as pd

df = pd.read_excel(r'团队成员季度销售额.xlsx',dtype=str)

转换后的数据类型:

print(df.dtypes)

姓名 object
片区 object
1季度 object
2季度 object
3季度 object
4季度 object
dtype: object

所有列的数据类型,都被转换为 object

如果Excel文件中包含无法被转换为目标数据类型的数据,会报错 ValueError:

import pandas as pd
import numpy as np

df = pd.read_excel(r'团队成员季度销售额.xlsx', dtype=np.int32)
print(df.dtypes)

例图2  dtype参数引发ValueError



示例:dtype参数以字典的方式传入多个数据类型对象

以字典的方式传入数据类型,可以为不同的列指定不同的数据类型:

import pandas as pd
import numpy as np

df = pd.read_excel(r'团队成员季度销售额.xlsx', dtype={'1季度': np.float16, '2季度': np.int32})

查看转换后的数据类型:

print(df.dtypes)

姓名 object
片区 object
1季度 float16
2季度 int32
3季度 int64
4季度 int64
dtype: object



示例:使用converters参数格式化日期时间

1、观察转换前的数据类型,及数据样式:

import pandas as pd

df = pd.read_excel(r'团队成员日销售额.xlsx')

转换前的数据类型

print(df.dtypes)

日期 object
姓名 object
工号 object
职级 object
片区 object
业绩 float64
dtype: object

转换前的数据样式:

print(df.head(2))
日期姓名工号职级片区业绩
02021~3~1OliviaA1349销售员华南523.9
12021~3~2LiamA1880经理华南16647.5

观察上面的结果,注意此时日期列的数据,格式为 yyyy~mm~dd 的形式。并且其数据类型并不是 datetime64[ns]

2、使用 converters 参数,以传入字典的方式结合自定义函数,指定某列转换为什么类型:

import pandas as pd

# 自定义转换函数,这里示例将 "日期" 列的日期字符串转换为年~月~日的形式
def custom_date_converter(cell_content):    
    cell_content = cell_content.replace('~','-')
    return pd.to_datetime(cell_content, format='%Y-%m-%d')

# 读取 Excel 文件并应用转换函数
df = pd.read_excel(r'E:\Project\Pandas学习笔记\数据集\团队成员日销售额.xlsx', converters={'日期': custom_date_converter})

转换后的数据类型:

print(df.dtypes)

日期 datetime64[ns]
姓名 object
工号 object
职级 object
片区 object
业绩 float64
dtype: object

转换后的数据样式:

print(df.head(2))
日期姓名工号职级片区业绩
02021-03-01OliviaA1349销售员华南523.9
12021-03-02LiamA1880经理华南16647.5

观察上面的结果,日期列的数据,以及被转换为 yyyy-mm-dd 的形式。并且其数据类型已经是 datetime64[ns]



示例:dtype参数和converters若指向了同一列,dtype的转换不会生效。并且会报出提示,但不会影响程序运行。

import pandas as pd
import numpy as np


# 自定义转换函数,这里示例将 "日期" 列的日期字符串转换为年-月-日的形式,并将数据类型设置为datetime64
def custom_date_converter(cell_content):    
    cell_content = cell_content.replace('~','-')
    return pd.to_datetime(cell_content, format='%Y-%m-%d')


# 读取 Excel 同时使用dtype和convertes两个参数,对相同的列进行转换
df = pd.read_excel(r'E:\Project\Pandas学习笔记\数据集\团队成员日销售额.xlsx',dtype={'日期': str},converters={'日期': custom_date_converter} )
C:\Users\Administrator\AppData\Local\Temp\ipykernel_23596\1553981442.py:12: ParserWarning: Both a converter and dtype were specified for column 日期 - only the converter will be used.
  df = pd.read_excel(r'E:\Project\Pandas学习笔记\数据集\团队成员日销售额.xlsx',dtype={'日期': str},converters={'日期': custom_date_converter} )

如上所示,读取文件时候,若dtype参数和converters若指向了同一列,会有个提示报出。

查看转换后的数据类型:

print(df.dtypes)

日期 datetime64[ns]
姓名 object
工号 object
职级 object
片区 object
业绩 float64
dtype: object

由上面的结果可见,dtype参数和converters若指向了同一列,dtype的转换不会生效。并且会报出提示,但不会影响程序运行。日期列成功转换为 datetime64[ns]



示例:dtype参数和converters若指向了不同的列,两个参数都会生效,相当于一种互补行为

import pandas as pd
import numpy as np

# 自定义转换函数,这里示例将 "日期" 列的日期字符串转换为年-月-日的形式,并将数据类型设置为datetime64
def custom_date_converter(cell_content):
    cell_content = cell_content.replace('~','-')
    return pd.to_datetime(cell_content, format='%Y-%m-%d')

# 读取 Excel 文件并应用转换函数
df = pd.read_excel(r'团队成员日销售额.xlsx', dtype={'业绩':np.float64},converters={'日期': custom_date_converter})

查看数据类型:

print(df.dtypes)

日期 datetime64[ns]
姓名 object
工号 object
职级 object
片区 object
业绩 float64
dtype: object

查看数据样式:

print(df.head(2))
日期姓名工号职级片区业绩
02021-03-01OliviaA1349销售员华南523.9
12021-03-02LiamA1880经理华南16647.5

由上面的结果可见,“日期”列和“业绩”列,都转换为目标数据类型,此时的 converters 参数和 dtype 参数发生了互补行为。



示例:ture_values参数和false_values参数的使用

  • 只有整列内容被转换为true或false,数据类型才会转换。
  • 数字类型的值,不会被转换为true或false,数据类型也不会改变。
import pandas as pd
from io import BytesIO

# 构建一个演示用的DataFrame,a列由1和0组成,b列由true,false组成,c列由yes,no组成
df = pd.DataFrame({'a': [1, 0],
                   'b': ['true', 'false'], 
                   'c': ['yes', 'no']})

# 将 DataFrame 写入内存中的 Excel 文件
excel_buffer = BytesIO()
df.to_excel(excel_buffer, index=False, engine='openpyxl')
excel_buffer.seek(0)

# 在没指定true_values 和 false_values 的情况下读取内容
df2 = pd.read_excel(excel_buffer, engine='openpyxl')

# 在没指定true_values 和 false_values 的情况下,观察read_excel读取到的内容及数据类型
print('数据类型:\n',df2.dtypes)
print('数据样式:')
print(df2)

数据类型:
a int64
b bool
c object
dtype: object
数据样式:
a b c
0 1 True yes
1 0 False no

查看数据类型:

print(df2.dtypes)

a int64
b bool
c object
dtype: object

查看数据样式:

print(df2)
abc
01Trueyes
10Falseno

尝试转换真假值:

# 用read_excel,读取内存里的表格,并指定可以转换的内容
df3 = pd.read_excel(excel_buffer, engine='openpyxl',true_values=[1,'yes'],false_values=[0,'no'])

观察转换后的数据类型:

print(df3.dtypes)

a int64
b bool
c bool
dtype: object

观察转换后的数据样式:

print(df3)
abc
01TrueTrue
10FalseFalse


示例:skiprows参数传入可调用对象(callable),实现复杂的跳行功能

# 跳过 0-10行
pd.read_excel(r'文件路径',skiprows=lambda x: x in range(0,10))

# 跳过奇数行
pd.read_excel(r'文件路径', skiprows=lambda x: x % 2 == 1)

# 使用自定义函数也可以
def skip_even(row_number):
    if row_number % 2 == 0:
        return row_number

pd.read_excel(r'文件路径', skiprows=skip_even)


示例:把指定内容转换为缺失值

1、观察原始数据:

import pandas as pd
#读取数据
df = pd.read_excel(r'团队成员季度销售额.xlsx')

原始数据的样子:

print(df.head(2))
姓名片区1季度2季度3季度4季度
0左院梅华南1491108350009461
1左艳艳华南1106576234392359

2、把字符串 ‘华南’ 转换为缺失值:

# 把字符串 ‘华南’ 转换为缺失值
df = pd.read_excel(r'团队成员季度销售额.xlsx', na_values='华南')

3、观察转换后的样子:

print(df.head(2))
姓名片区1季度2季度3季度4季度
0左院梅NaN1491108350009461
1左艳艳NaN1106576234392359


示例:verbose参数的使用示例

import pandas as pd

# 读取文件时,开启verbose,输出更多细节
df = pd.read_excel(r'E:\Project\Pandas学习笔记\附件\数据集\团队成员季度销售额.xlsx', na_values='华南',verbose=True)
# 即便不输出df,只要开始读取文件,就会有细节被输出,如下:
Reading sheet 0


示例:Excel里文本格式的数据,无法被自动解析为日期时间类型(datetime64[ns]

1、观察原始数据:

import pandas as pd
# 读取测试文件
df = pd.read_excel(r'日期时间解析测试用表.xlsx')

查看原始数据类型:

print(df.dtypes)

年 int64
月 int64
日 int64
月/日 object
年月日 object
时间 object
日期和时间 object
dtype: object

观察上面的结果可以发现,原始数据里,并没有任何一列,被解析为 datetime64[ns]



示例:parse_dates传入一维列表,指定的列,会被解析为datetime64[ns]

1、读取文件,并观察原始数据

import pandas as pd
df = pd.read_excel(r'日期时间解析测试用表.xlsx')

观察原始数据类型:

print(df.dtypes)

年 int64
月 int64
日 int64
月/日 object
年月日 object
时间 object
日期和时间 object
dtype: object

观察原始数据的样式:

print(df.head(2))
月/日年月日时间日期和时间
02023141/22023/01/0122:20:132023/1/5 20:02:02
12023251/32023/01/0222:20:142023/1/5 20:02:03

2、parse_dates传入一维列表

import pandas as pd
df = pd.read_excel(r'日期时间解析测试用表.xlsx', parse_dates=['年','年月日'])

解析后的数据类型:

print(df.dtypes)

年 datetime64[ns]
月 int64
日 int64
月/日 object
年月日 datetime64[ns]
时间 object
日期和时间 object
dtype: object

解析后的数据样式:

print(df.head(2))
月/日年月日时间日期和时间
02023-01-01141/22023-01-0122:20:132023/1/5 20:02:02
12023-01-01251/32023-01-0222:20:142023/1/5 20:02:03

观察上面结果,parse_dates 传入一维列表后,指定的列,被解析为 datetime64[ns] 数据类型



示例:parse_dates传入二维列表,指定的列,会被组合并解析为datetime64[ns],原来的列会被移除

1、读取数据并观察原始数据

import pandas as pd
df = pd.read_excel(r'日期时间解析测试用表.xlsx')

观察原始数据类型:

print(df.dtypes)

年 int64
月 int64
日 int64
月/日 object
年月日 object
时间 object
日期和时间 object
dtype: object

观察原始数据样式:

print(df.head(2))
月/日年月日时间日期和时间
02023141/22023/01/0122:20:132023/1/5 20:02:02
12023251/32023/01/0222:20:142023/1/5 20:02:03

2、parse_dates传入二维列表,解析日期时间

import pandas as pd
df = pd.read_excel(r'日期时间解析测试用表.xlsx', parse_dates=[[0,1,2]])

观察解析后的数据类型:

print(df.dtypes)

年_月_日 datetime64[ns]
月/日 object
年月日 object
时间 object
日期和时间 object
dtype: object

观察解析后的数据样式

print(df.head(2))
年_月_日月/日年月日时间日期和时间
02023-01-041/22023/01/0122:20:132023/1/5 20:02:02
12023-02-051/32023/01/0222:20:142023/1/5 20:02:03

观察上面结果,当 parse_dates 参数传入二维列表列表中指定的列,会被合并为一个新的日期时间列,并且数据类型被解析为 datetime64[ns]



示例:parse_dates传入字典,指定的列,会被组合并解析为datetime64[ns],原来的列会被移除

1、读取数据并观察原始数据

import pandas as pd
df = pd.read_excel(r'日期时间解析测试用表.xlsx')

观察原始数据类型:

print(df.dtypes)

年 int64
月 int64
日 int64
月/日 object
年月日 object
时间 object
日期和时间 object
dtype: object

观察原始数据样式:

df.head(2)
月/日年月日时间日期和时间
02023141/22023/01/0122:20:132023/1/5 20:02:02
12023251/32023/01/0222:20:142023/1/5 20:02:03

2、parse_dates传入字典,解析日期时间

import pandas as pd
df = pd.read_excel(r'日期时间解析测试用表.xlsx', parse_dates={'new_date':[0,1,2]})

观察解析后的数据类型:

print(df.dtypes)

new_date datetime64[ns]
月/日 object
年月日 object
时间 object
日期和时间 object
dtype: object

观察解析后的数据样式

print(df.head(2))
new_date月/日年月日时间日期和时间
02023-01-041/22023/01/0122:20:132023/1/5 20:02:02
12023-02-051/32023/01/0222:20:142023/1/5 20:02:03

通过上面的结果可以发现,指定的列,会被组合为一个新的列,新列的名字有字典的键指定。并解析为datetime64[ns],原来的列会被移除



示例:date_format参数的使用

import pandas as pd
# 只处理一列,就用单个字符串
df = pd.read_csv('文件路径', parse_dates=['日期'], date_format='%Y-%m-%d')  
# 处理多列,可以用字典
df = pd.read_csv('文件路径', parse_dates=['订单日期','成交日期'], date_format={'订单日期': '%Y-%m-%d','成交日期': '%Y-%m-%d'}) 


示例:标准千分符数字,在Excel里如果以文本格式存储,则无法正确识别为数字。非标准千分符,无论如何都无法识别为数字

1、观察数据样式:

import pandas as pd

# 替换为你自己的文件存储位置
df = pd.read_excel(r'数字解析测试用表.xlsx')

# 输出数据样式
print(df.head(2))
常规文本常规+标准千分文本+标准千分常规+非标千分文本+非标千分
0111001500015,0001~200.51~200.5
11002001500015,0011~200.61~200.6

2、观察数据类型:

print('运行结果:\n\n',df.dtypes)

运行结果:
常规 int64
文本 int64
常规+标准千分 int64
文本+标准千分 object
常规+非标千分 object
文本+非标千分 object
dtype: object

可以发现:

1、含有 标准千分符的数字 但是由于在Excel里是以 文本格式 存储的,所以读取后并没有被识别为数字,而是识别为 object 数据类型。 如列:“文本+标准千分”。

2、含有 非标准千分符 的数字,无论是以文本格式存储,还是以其他格式存储,都无法识别为数字,而是识别为 object 数据类型。如列:“常规+非标千分”,“文本+非标千分”。

如果需要这种数据被识别为数字,则需要在读取Excel文件时,使用 thousands 参数,指定应该被识别为千分符的数字。

3、使用 thousands 参数指定千分符,使数字能够正确识别

import pandas as pd

# 替换为你自己的文件存储位置
df = pd.read_excel(r'数字解析测试用表.xlsx', thousands=',')

print('运行结果:\n\n',df.dtypes)

运行结果:
常规 int64
文本 int64
常规+标准千分 int64
文本+标准千分 int64
常规+非标千分 object
文本+非标千分 object
dtype: object

至此,“文本+标准千分” 这一列,已经被识别为数字了,其数据类型被识别为 int64

同理,如果想要把 ‘~’ 也识别为千分符,也可以用 thousands 参数指定。

⚠️ 注意 : thousands 参数,同时只能处理一种千分符,如果你的文件非常复杂,有很多种千分符号,你还想必须在读取文件时处理感觉,可以考虑搭配 read_excelconverters 参数进行处理。但是如果你的文件特别大,这样做会影响读取速度。



示例:含有标准小数点的数字,以任何格式存储,都可以正确识别。含有非标准小数点的数字,以任何格式存储,都无法正确识别

观察数据样式:

import pandas as pd

# 文件路径修改为你自己实际的存放位置,注意,用于小数点测试的数据,在工作表decimal里,需要用 `sheet_name` 参数指定
df = pd.read_excel(r'数字解析测试用表.xlsx', sheet_name='decimal')

# 输出数据样式
print(df.head(2))
常规文本常规+标准小数点文本+标准小数点常规+非标小数点文本+非标小数点
01110015000.215000.215000_215000_2
110020015000.215000.315000_315000_3

观察数据类型:

print('运行结果:\n\n',df.dtypes)

运行结果:
常规 int64
文本 int64
常规+标准小数点 float64
文本+标准小数点 float64
常规+非标小数点 object
文本+非标小数点 object
dtype: object

可以发现:

1、含有 小数点数的数字,无论以任何格式存储,都可以被正确识别为数字类型。 如“常规+标准小数点”,“文本+标准小数点”。

2**、含有小数点**准千分符 无论以任何格式存储格式存储,都为法识别位数字,而是识别为 object 数据类型。常规+非标小数点非标“文本+非标小数点”非标千分。

如果需要这种数据被识别为数字,则需要在读取Excel文decimalusands 参数,指定小数点识别为千分符的数字。

使用 decimal 参数指定小数点,使数字能够正确识别

import pandas as pd

# 文件路径修改为你自己实际的存放位置,注意,用于小数点测试的数据,在工作表decimal里,需要用 `sheet_name` 参数指定
df = pd.read_excel(r'数字解析测试用表.xlsx', sheet_name='decimal',decimal='_')

print('运行结果:\n\n',df.dtypes)

运行结果:
常规 int64
文本 int64
常规+标准小数点 float64
文本+标准小数点 float64
常规+非标小数点 float64
文本+非标小数点 float64
dtype: object

至此,“常规+非标小数点” 和 “文本+非标小数点” 这两列,已经被识别为数字了,其数据类型被识别为 float64

⚠️ 注意 : decimal 参数,同时只能处理一种小数点符号,如果你的文件非常复杂,有很多种小数点类型的数字,你还想必须在读取文件时处理感觉,可以考虑搭配 read_excelconverters 参数进行处理。但是如果你的文件特别大,这样做会影响读取速度。



示例:使用comment参数忽略注释内容

1、读取测试文件:

import pandas as pd

df = pd.read_excel(r'E:\Project\Pandas学习笔记\数据集\含有注释符的测试文件.xlsx')

观察原始样式:

print(df)
内容内容2
0# 关于明天工作的说明: 明天集体加班!#张三超级爱加班
1# 明天要加班 # 不加班的要提前通知张三是卷王
2不!我绝不加班# 张三没有李四卷
3没有天理了# 关于明天工作的说明: 明天集体加班!
4当个人吧!佛系

以这个测试文件为例,# 是注释符,读取excel文件的时候希望忽略掉。

2、 使用comment参数忽略掉注释内容:

import pandas as pd

df = pd.read_excel(r'E:\Project\Pandas学习笔记\数据集\含有注释符的测试文件.xlsx', comment='#')

观察注释后的数据:

print(df)
内容内容2
0不!我绝不加班None
1没有天理了None
2当个人吧!佛系

观察上面的结果可以发现:

  • 1、单元格内容(# 关于明天工作的说明: 明天集体加班!#) 此内容因为是在这一行的最开头,所以从这里开始,整行数据都被忽略掉了。
  • 2、单元格内容(# 张三没有李四卷) 因为在这一行不是最开头,所以它前面的数据被保留了下来。

这与参数描述的内容相吻合。

示例:读/写远程文件

可以传入 URL 来读取或写入远程文件到 pandas 的许多 IO 函数 - 以下示例为读取远程 Excel 文件:

df = pd.read_exce("https://download.bls.gov/pub/time.series/cu/cu.item")

将标头键值映射字典传递到 storage_options ,可以将自定义标头与 HTTP(s) 请求一起发送,如下所示:

headers = {"User-Agent": "pandas"}
df = pd.read_csv(
    "https://download.bls.gov/pub/time.series/cu/cu.item",
    sep="\t",
    storage_options=headers
)

所有非本地文件或 HTTP 的 URL 均由 fsspec(如果已安装)及其各种文件系统处理。(包括 Amazon S3、Google Cloud、SSH、FTP、webHDFS…)其中一些实现需要安装额外的软件包,例如 S3 URL 需要s3fs库:

在处理远程存储系统时,您可能需要使用环境变量或特殊位置的配置文件进行额外配置。例如,要访问 S3 存储桶中的数据,您需要使用S3Fs 文档中列出的几种方式之一定义凭据。

storage_options = {"client_kwargs": {"endpoint_url": "http://127.0.0.1:5555"}}}
df = pd.read_json("s3://pandas-test/test-1", storage_options=storage_options)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数象限

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值