如果您和我一样经常用 Python 做数据分析,很快就会发现读取 CSV 文件是最常见的任务之一。然而,随着数据集规模增长,这种方式可能会变得缓慢或占用大量内存。
Polars 是一个快速、现代的 Python DataFrame 库,被设计为 Pandas 的高性能替代方案。它专注于速度和低内存占用,因此比传统工具更从容地处理大型数据集。
Polars 的核心函数 pl.read_csv() 提供了将 CSV 文件加载为 DataFrame 的简洁方案,并内置解析、数据类型与内存控制等选项。
在本指南中,我将演示如何使用 Polars 的 pl.read_csv() 读取 CSV 文件、控制解析行为并处理大型数据集。如果您刚开始使用,欢迎查看我们的Introduction to Polars 课程,学习如何用 Polars 处理数据并提取洞见。
pl.read_csv() 的基本用法
在继续之前,先查看我们的 Python Polars 教程,了解如何配置环境。
现在,让我们看看 pl.read_csv() 的工作方式:
import polars as pl
fuel_data = pl. read_csv( "Fuel_Consumption_2000-2022.csv" )
print ( fuel_data. head( ) ) 技术支持
在上述示例中,Polars 读取文件并将其加载到 DataFrame 中。该函数返回一个 Polars DataFrame,这是一种表格数据结构,类似于您在 pandas 中得到的对象。
默认情况下,pl.read_csv():
pl.read_csv() 的常用参数
了解 pl.read_csv() 如何加载数据之后,我们来看如何使用以下参数来定制 Polars 的解析过程。
文件路径与数据源
Polars 允许从不同数据源加载数据。您可以传入本地的字符串路径、Pathlib 对象,甚至是 URL。比如,下面的代码从网络读取一个包含各国历年 GDP 的大型 CSV 文件。
url = "https://raw.githubusercontent.com/datasets/gdp/master/data/gdp.csv"
gdp_data = pl. read_csv( url) 技术支持
分隔符与定界符
并非所有 CSV 文件都使用逗号。您可以使用 separator 参数处理制表符、分号、竖线或其他字符。下面的示例展示了读取文件时如何指定分隔符。
sales_data = pl. read_csv( "2024_sales.csv" , separator= ";" )
orders_data = pl. read_csv( "all_orders.tsv" , separator= "\t" ) 技术支持
表头处理
如前所述,Polars 假定数据的第一行包含列名。如果您的文件没有表头行,请使用参数 has_header=False,如下所示。Polars 会自动分配列名,如 column_1、column_2、column_3 等。
orders_data = pl. read_csv( "all_orders.csv" , has_header= False ) 技术支持
您也可以通过提供特定列名来重命名列。例如:
sales_data = pl. read_csv( "sales_April.csv" , new_columns= [
"OrderDate" , "OrderNumber" , "ProductKey" , "SalespersonKey" , "Salesperson" ] ) 技术支持
编码
不同的 CSV 文件可能使用不同的文本编码。如果遇到异常字符或报错,请指定编码:
fuel_data = pl. read_csv( "Fuel_Consumption_2000-2022.csv" , encoding= "utf8" ) 技术支持
其他常见编码选项包括 ”latin1” 和 ”utf8-lossy”,它们会适当处理无效字符。
在 Polars 中读取 CSV 时如何选择列
处理大型 CSV 文件时,您往往并不需要所有列。Polars 允许使用 columns 参数仅加载所需列。
fuel_data = pl. read_csv( "Fuel_Consumption_2000-2022.csv" ,
columns= [ "YEAR" , "MAKE" , "MODEL" ]
) 技术支持
在加载文件时只选择需要的列,可以避免加载不必要的数据,从而减少内存占用。这种做法也能加快读取速度并提升整体管道性能。
在 Polars CSV 中处理数据类型(模式)
Polars 是强类型库,这意味着每一列都必须有一致的数据类型,例如全为整数或全为字符串。
自动类型推断
默认情况下,Polars 会检查数据并自动确定列类型。该方法在大多数情况下表现良好,但有时可能会误判列类型,比如把 ID 当作整数而非字符串。
手动指定模式
当您希望 DataFrame 具有一致性时,应手动指定数据模式。这可确保在多个文件之间保持一致,并避免后续处理中的类型相关错误。
在大多数场景下,使用 schema_overrides 为特定列指定数据类型,同时允许 Polars 推断其余列。
import polars as pl
empl_data = pl. read_csv(
"all_employees.csv" ,
schema_overrides= {
"id" : pl. Int64,
"name" : pl. String,
"age" : pl. Int64,
"salary" : pl. Float64
}
) 技术支持
或者使用 schema 定义 DataFrame 的完整结构。
empl_data = pl. read_csv(
"all_employees.csv" ,
schema= {
"id" : pl. Int64,
"name" : pl. String,
"age" : pl. Int64,
"salary" : pl. Float64
}
) 技术支持
在 Polars CSV 中处理缺失值
默认情况下,Polars 会自动检测这些缺失值,并将其表示为 null。有时缺失值由特定字符串表示,如 ”NA”、”N/A” 或 ”missing”。您可以通过 null_values 定义这些标记,使其被视为 null。
survey_data = pl. read_csv(
"survey_results.csv" ,
null_values= [ "N/A" , "EMPTY" , "null" ]
) 技术支持
正确处理缺失值有助于确保数据类型一致、避免错误计算,从而降低分析与建模过程中的错误率。
在 Polars 中读取大型 CSV 文件
当处理超过可用内存的大型数据集时,Polars 表现尤为出色,因为它可以在不一次性加载整个文件的情况下处理数据。
使用 scan_csv() 的惰性加载
与 read_csv() 立即将数据加载到内存不同,Polars 提供了惰性方案 scan_csv(),它会构建优化后的查询计划,并仅在需要时执行操作。
在下面的示例中,pl.scan_csv 在不加载文件的情况下扫描 CSV,构建仅获取“YEAR”“MAKE”“MODEL”列且品牌为“ACURA”的查询,然后执行该查询。这样只会将过滤后的数据片段加载到内存,而不是整个文件。
fuel_consumption = pl. scan_csv( "Fuel_Consumption_2000-2022.csv" )
fuel_consumption_filtered = fuel_consumption. select(
[ "YEAR" , "MAKE" , "MODEL" ] ) . filter ( pl. col( "MAKE" ) == "ACURA" )
fuel_consumption_acura = fuel_consumption_filtered. collect( ) 技术支持
我建议在以下情况下使用 scan_csv():
处理无法舒适放入内存的大文件
需要应用多步转换,例如筛选、选择和聚合数据
希望在执行前进行查询优化
流式处理与内存效率
Polars 还允许以分块的方式进行流式处理,使峰值内存与文件大小无关而保持稳定。
对于大型 CSV 文件,先用 scan_csv() 创建惰性查询。调用 scan_csv() 时文件并不会被完全加载。
fuel_consumption = pl. scan_csv( "Fuel_Consumption_2000-2022.csv" ,
low_memory= True ) 技术支持
由于上述方法仍使用 read_csv,最佳做法是将惰性执行与流式处理结合使用。
在下面的示例中,Polars 以流水线方式按批逐行处理文件,任意时刻只在内存中保留过滤后的行(“CYLINDERS” > 3)。
fuel_consumption = pl. scan_csv( "Fuel_Consumption_2000-2022.csv" )
result = fuel_consumption. filter ( pl. col( "CYLINDERS" ) > 3 )
fuel_consumption_high = result. collect( engine= "streaming" ) 技术支持
与 Pandas 的性能对比
与 pandas 相比,Polars 在 CSV 读取与处理方面通常表现更佳,下一节将看到对比。
Polars read_csv vs Pandas read_csv
下表总结了在 Python 中读取 CSV 时 Polars 与 Pandas 的差异。
方面
Polars
Pandas
速度
因多线程与优化解析而更快
在大文件上较慢(多数为单线程)
内存占用
占用更低;支持惰性 + 流式处理
积极加载,将整个数据集读入内存
语法
pl.read_csv(“data.csv”)
pd.read_csv(“data.csv”)
执行模型
支持惰性执行(scan_csv)
仅支持即时(积极)执行
优化
内置查询优化(列裁剪、筛选)
自动优化能力有限
最佳用例
大型数据集、对性能敏感的流程
较小数据集、快速分析
我建议阅读我们关于 Pandas 与 Polars 的对比 ,以确定哪种工具更适合您的分析需求。
从不同来源读取 CSV
正如前文所示,您可以使用 Polars 从不同来源读取 CSV 文件。上述示例中我已展示如何从本地文件与 URL 读取 CSV。
此外,Polars 可自动处理压缩的 CSV 文件。例如,以下代码从 .gzip 文件读取数据。
census_data = pl. read_csv( "2018_census.csv.gz" ) 技术支持
常见错误与排查
即便使用像 Polars 这样的高性能引擎,读取 CSV 文件时仍可能遇到一些问题。以下是我遇到的常见问题及其解决方法。
编码错误: 您可能会看到类似 UnicodeDecodeError 的错误,意味着文件不是 UTF-8 编码。这在较老的文件或某些版本 Excel 导出的 CSV 中较常见。要解决此问题,请设置合适的编码,或在字符不一致或有损坏时使用 “utf8-lossy”。
分隔符问题: 如果 DataFrame 成功加载但所有数据都挤在单列中,说明 Polars 未识别到分隔符。为解决此问题,请通过 separator 参数显式设置正确的分隔符,如分号(;)、制表符(\t)或竖线(|)。
数据类型不正确: 有时 Polars 可能错误推断列类型,例如把数值型 ID 读成字符串,或在解析时出错。此时可使用 schema_overrides 为特定列指定类型;若希望为每一列都定义类型,请使用 schema。您也可以增大 infer_schema_length,让 Polars 在推断模式前检查更多行。
大文件内存问题: 如果在加载大文件时 Python 进程崩溃,说明内存不足。要解决此问题,请从 read_csv() 切换到 scan_csv() 进行惰性加载,以降低内存占用并提升性能。您也可以只加载数据集的部分列,或使用流式执行按块加载数据。
结语
Polars 的 read_csv() 使用简单,却足以胜任实际任务。在我看来,面对不断增长的数据集时,Polars 具有明显优势。
接下来,欢迎阅读我们关 于 Polars GPU 引擎 的博文,了解其多种应用。如果您准备上手实战,我们的 Super Bowl Analytics with Polars 代码跟练将帮助您解决真实分析问题、进行计算,并将基础的机器学习技术应用于体育分析问题。
如果您和我一样经常用 Python 做数据分析,很快就会发现读取 CSV 文件是最常见的任务之一。然而,随着数据集规模增长,这种方式可能会变得缓慢或占用大量内存。
Polars 是一个快速、现代的 Python DataFrame 库,被设计为 Pandas 的高性能替代方案。它专注于速度和低内存占用,因此比传统工具更从容地处理大型数据集。
Polars 的核心函数
pl.read_csv()提供了将 CSV 文件加载为 DataFrame 的简洁方案,并内置解析、数据类型与内存控制等选项。在本指南中,我将演示如何使用 Polars 的
pl.read_csv()读取 CSV 文件、控制解析行为并处理大型数据集。如果您刚开始使用,欢迎查看我们的Introduction to Polars课程,学习如何用 Polars 处理数据并提取洞见。pl.read_csv() 的基本用法
在继续之前,先查看我们的 Python Polars 教程,了解如何配置环境。
现在,让我们看看
pl.read_csv()的工作方式:在上述示例中,Polars 读取文件并将其加载到 DataFrame 中。该函数返回一个 Polars DataFrame,这是一种表格数据结构,类似于您在 pandas 中得到的对象。
默认情况下,
pl.read_csv():假定第一行包含列名(
has_header=True)自动推断列的数据类型
使用逗号(
,)作为分隔符将整个文件读入内存
pl.read_csv() 的常用参数
了解
pl.read_csv()如何加载数据之后,我们来看如何使用以下参数来定制 Polars 的解析过程。文件路径与数据源
Polars 允许从不同数据源加载数据。您可以传入本地的字符串路径、
Pathlib对象,甚至是 URL。比如,下面的代码从网络读取一个包含各国历年 GDP 的大型 CSV 文件。分隔符与定界符
并非所有 CSV 文件都使用逗号。您可以使用
separator参数处理制表符、分号、竖线或其他字符。下面的示例展示了读取文件时如何指定分隔符。表头处理
如前所述,Polars 假定数据的第一行包含列名。如果您的文件没有表头行,请使用参数
has_header=False,如下所示。Polars 会自动分配列名,如column_1、column_2、column_3等。您也可以通过提供特定列名来重命名列。例如:
编码
不同的 CSV 文件可能使用不同的文本编码。如果遇到异常字符或报错,请指定编码:
其他常见编码选项包括
”latin1”和”utf8-lossy”,它们会适当处理无效字符。在 Polars 中读取 CSV 时如何选择列
处理大型 CSV 文件时,您往往并不需要所有列。Polars 允许使用
columns参数仅加载所需列。在加载文件时只选择需要的列,可以避免加载不必要的数据,从而减少内存占用。这种做法也能加快读取速度并提升整体管道性能。
在 Polars CSV 中处理数据类型(模式)
Polars 是强类型库,这意味着每一列都必须有一致的数据类型,例如全为整数或全为字符串。
自动类型推断
默认情况下,Polars 会检查数据并自动确定列类型。该方法在大多数情况下表现良好,但有时可能会误判列类型,比如把 ID 当作整数而非字符串。
手动指定模式
当您希望 DataFrame 具有一致性时,应手动指定数据模式。这可确保在多个文件之间保持一致,并避免后续处理中的类型相关错误。
在大多数场景下,使用
schema_overrides为特定列指定数据类型,同时允许 Polars 推断其余列。或者使用
schema定义 DataFrame 的完整结构。在 Polars CSV 中处理缺失值
默认情况下,Polars 会自动检测这些缺失值,并将其表示为
null。有时缺失值由特定字符串表示,如”NA”、”N/A”或”missing”。您可以通过null_values定义这些标记,使其被视为null。正确处理缺失值有助于确保数据类型一致、避免错误计算,从而降低分析与建模过程中的错误率。
在 Polars 中读取大型 CSV 文件
当处理超过可用内存的大型数据集时,Polars 表现尤为出色,因为它可以在不一次性加载整个文件的情况下处理数据。
使用 scan_csv() 的惰性加载
与
read_csv()立即将数据加载到内存不同,Polars 提供了惰性方案scan_csv(),它会构建优化后的查询计划,并仅在需要时执行操作。在下面的示例中,
pl.scan_csv在不加载文件的情况下扫描 CSV,构建仅获取“YEAR”“MAKE”“MODEL”列且品牌为“ACURA”的查询,然后执行该查询。这样只会将过滤后的数据片段加载到内存,而不是整个文件。我建议在以下情况下使用
scan_csv():流式处理与内存效率
Polars 还允许以分块的方式进行流式处理,使峰值内存与文件大小无关而保持稳定。
对于大型 CSV 文件,先用
scan_csv()创建惰性查询。调用scan_csv()时文件并不会被完全加载。由于上述方法仍使用
read_csv,最佳做法是将惰性执行与流式处理结合使用。在下面的示例中,Polars 以流水线方式按批逐行处理文件,任意时刻只在内存中保留过滤后的行(
“CYLINDERS” > 3)。与 Pandas 的性能对比
与 pandas 相比,Polars 在 CSV 读取与处理方面通常表现更佳,下一节将看到对比。
Polars read_csv vs Pandas read_csv
下表总结了在 Python 中读取 CSV 时 Polars 与 Pandas 的差异。
方面
Polars
Pandas
速度
因多线程与优化解析而更快
在大文件上较慢(多数为单线程)
内存占用
占用更低;支持惰性 + 流式处理
积极加载,将整个数据集读入内存
语法
pl.read_csv(“data.csv”)pd.read_csv(“data.csv”)执行模型
支持惰性执行(
scan_csv)仅支持即时(积极)执行
优化
内置查询优化(列裁剪、筛选)
自动优化能力有限
最佳用例
大型数据集、对性能敏感的流程
较小数据集、快速分析
我建议阅读我们关于 Pandas 与 Polars 的对比,以确定哪种工具更适合您的分析需求。
从不同来源读取 CSV
正如前文所示,您可以使用 Polars 从不同来源读取 CSV 文件。上述示例中我已展示如何从本地文件与 URL 读取 CSV。
此外,Polars 可自动处理压缩的 CSV 文件。例如,以下代码从
.gzip文件读取数据。常见错误与排查
即便使用像 Polars 这样的高性能引擎,读取 CSV 文件时仍可能遇到一些问题。以下是我遇到的常见问题及其解决方法。
编码错误: 您可能会看到类似
UnicodeDecodeError的错误,意味着文件不是 UTF-8 编码。这在较老的文件或某些版本 Excel 导出的 CSV 中较常见。要解决此问题,请设置合适的编码,或在字符不一致或有损坏时使用“utf8-lossy”。分隔符问题: 如果 DataFrame 成功加载但所有数据都挤在单列中,说明 Polars 未识别到分隔符。为解决此问题,请通过
separator参数显式设置正确的分隔符,如分号(;)、制表符(\t)或竖线(|)。数据类型不正确: 有时 Polars 可能错误推断列类型,例如把数值型 ID 读成字符串,或在解析时出错。此时可使用
schema_overrides为特定列指定类型;若希望为每一列都定义类型,请使用schema。您也可以增大infer_schema_length,让 Polars 在推断模式前检查更多行。大文件内存问题: 如果在加载大文件时 Python 进程崩溃,说明内存不足。要解决此问题,请从
read_csv()切换到scan_csv()进行惰性加载,以降低内存占用并提升性能。您也可以只加载数据集的部分列,或使用流式执行按块加载数据。结语
Polars 的
read_csv()使用简单,却足以胜任实际任务。在我看来,面对不断增长的数据集时,Polars 具有明显优势。接下来,欢迎阅读我们关于 Polars GPU 引擎 的博文,了解其多种应用。如果您准备上手实战,我们的 Super Bowl Analytics with Polars 代码跟练将帮助您解决真实分析问题、进行计算,并将基础的机器学习技术应用于体育分析问题。