目 录CONTENT

文章目录

即使是初学者,也能在 Python 中处理大型数据集的方法

Administrator
2025-12-18 / 0 评论 / 0 点赞 / 0 阅读 / 0 字

📢 转载信息

原文链接:https://www.kdnuggets.com/how-to-handle-large-datasets-in-python-even-if-youre-a-beginner

原文作者:Bala Priya C


How to Handle Large Datasets in Python Even If You're a Beginner
Image by Author

 

# 引言

 
在 Python 中处理大型数据集时,一个常见的问题是:当你使用 Pandas 加载数据时,程序会变得异常缓慢甚至完全崩溃。这通常是因为你试图一次性将所有数据加载到内存中。

大多数内存问题源于你加载和处理数据的方式。通过一些实用的技巧,你可以处理远超可用内存限制的数据集。

在本文中,你将学习七种在 Python 中高效处理大型数据集的技术。我们将从简单的方法开始逐步深入,直到你完全清楚哪种方法最适合你的用例。

🔗 你可以在 GitHub 上找到代码。如果你愿意,可以运行这个 示例数据生成器 Python 脚本 来获取样本 CSV 文件,并使用代码片段进行处理。

 

# 1. 分块读取数据

 
最适合初学者的方法是分块处理数据,而不是一次性加载所有数据。

假设你有一个大型销售数据集,目标是计算总收入。以下代码演示了这种方法:

import pandas as pd # 定义块大小(每块的行数) chunk_size = 100000 total_revenue = 0 # 分块读取和处理文件 for chunk in pd.read_csv('large_sales_data.csv', chunksize=chunk_size): # 处理每个块 total_revenue += chunk['revenue'].sum() print(f"Total Revenue: ${total_revenue:,.2f}")

 

我们不是一次性加载全部 1000 万行,而是每次加载 10 万行。我们计算每个块的总和,并将其累加到运行总数中。无论文件有多大,你的 RAM 中最多只保留 10 万行。

何时使用: 当你需要对大型文件执行聚合(求和、计数、平均)或筛选操作时。
 

# 2. 只使用特定列

 
很多时候,你并不需要数据集中所有的列。只加载你需要的数据可以显著减少内存使用。

假设你正在分析客户数据,但只需要年龄和购买金额,而不是众多其他列:

import pandas as pd # 只加载你真正需要的列 columns_to_use = ['customer_id', 'age', 'purchase_amount'] df = pd.read_csv('customers.csv', usecols=columns_to_use) # 现在处理一个轻量得多的数据框 average_purchase = df.groupby('age')['purchase_amount'].mean() print(average_purchase)

 

通过指定 usecols,Pandas 只会将这三列加载到内存中。如果你的原始文件有 50 列,那么你的内存使用量就减少了大约 94%。

何时使用: 当你在加载数据之前就确切知道需要哪些列时。
 

# 3. 优化数据类型

 
默认情况下,Pandas 可能会使用比必需更多的内存。一个整数列可能被存储为 64 位,而 8 位可能就足够了。

例如,如果你正在加载一个包含产品评分(1-5 星)和用户 ID 的数据集:

import pandas as pd # 首先,让我们看看默认的内存使用情况 df = pd.read_csv('ratings.csv') print("Default memory usage:") print(df.memory_usage(deep=True)) # 现在优化数据类型 df['rating'] = df['rating'].astype('int8') # 评分范围是 1-5,所以 int8 足够了 df['user_id'] = df['user_id'].astype('int32') # 假设用户 ID 适合 int32 print("\nOptimized memory usage:") print(df.memory_usage(deep=True))

 

将评分列从可能的 int64(每个数字 8 字节)转换为 int8(每个数字 1 字节),我们为该列实现了 8 倍的内存减少。

常见转换包括:

  • int64int8, int16, 或 int32(取决于数字的范围)。
  • float64float32(如果你不需要极高的精度)。
  • objectcategory(用于包含重复值的列)。

 

# 4. 使用分类数据类型

 
当某一列包含重复的文本值(如国家名称或产品类别)时,Pandas 会分别存储每个值。category 数据类型会只存储一次唯一值,并使用高效的代码来引用它们。

假设你正在处理一个产品库存文件,其中“类别”列只有 20 个唯一值,但在整个数据集中重复出现:

import pandas as pd df = pd.read_csv('products.csv') # 转换前检查内存 print(f"Before: {df['category'].memory_usage(deep=True) / 1024**2:.2f} MB") # 转换为 category 类型 df['category'] = df['category'].astype('category') # 转换后检查内存 print(f"After: {df['category'].memory_usage(deep=True) / 1024**2:.2f} MB") # 它仍然像正常的文本数据一样工作 print(df['category'].value_counts())

 

这种转换可以显著减少低基数(唯一值少)列的内存使用量。该列的功能仍然与标准文本数据类似:你可以像平常一样进行筛选、分组和排序。

何时使用: 对于任何值频繁重复的文本列(类别、州、国家/地区等)。
 

# 5. 读取时筛选

 
有时你知道你只需要数据中的一部分行。与其加载所有内容后再进行筛选,不如在加载过程中进行筛选。

例如,如果你只关心 2024 年的交易记录:

import pandas as pd # 分块读取并筛选 chunk_size = 100000 filtered_chunks = [] for chunk in pd.read_csv('transactions.csv', chunksize=chunk_size): # 在存储前筛选每个块 filtered = chunk[chunk['year'] == 2024] filtered_chunks.append(filtered) # 合并筛选后的块 df_2024 = pd.concat(filtered_chunks, ignore_index=True) print(f"Loaded {len(df_2024)} rows from 2024")

 

我们将分块处理与筛选结合起来。在将每个块添加到列表中之前对其进行筛选,因此我们永远不会将整个数据集保留在内存中,只保留我们实际需要的行。

何时使用: 当你基于某些条件只需要一部分行时。
 

# 6. 使用 Dask 进行并行处理

 
对于真正庞大的数据集,Dask 提供了一个类似 Pandas 的 API,但它会自动处理所有分块和并行处理。

下面是如何在一个巨大的数据集中计算某一列的平均值:

import dask.dataframe as dd # 使用 Dask 读取(它会自动处理分块) df = dd.read_csv('huge_dataset.csv') # 操作看起来和 pandas 一样 result = df['sales'].mean() # Dask 是惰性的 - compute() 才会实际执行计算 average_sales = result.compute() print(f"Average Sales: ${average_sales:,.2f}")

 

Dask 不会将整个文件加载到内存中。相反,它会创建一个处理数据的计划,并在调用 .compute() 时执行该计划。它甚至可以使用多个 CPU 核心来加速计算。

何时使用: 当你的数据集大到 Pandas 即使分块也无法处理,或者当你希望在不编写复杂代码的情况下实现并行处理时。
 

# 7. 对数据进行采样以进行探索

 
当你在探索或测试代码时,你不需要完整的数据集。首先加载一个样本。

假设你正在构建一个机器学习模型并希望测试预处理流程。你可以按如下方式对数据集进行采样:

import pandas as pd # 只读取前 50,000 行 df_sample = pd.read_csv('huge_dataset.csv', nrows=50000) # 或者使用 skiprows 读取随机样本 import random skip_rows = lambda x: x > 0 and random.random() > 0.01 # 保留约 1% 的行 df_random_sample = pd.read_csv('huge_dataset.csv', skiprows=skip_rows) print(f"Sample size: {len(df_random_sample)} rows")

 

第一种方法加载前 N 行,适用于快速探索。第二种方法随机抽取文件中的行,更适合统计分析,或者当文件排序方式使得前几行不具有代表性时。

何时使用: 在开发、测试或探索性分析阶段,运行代码前。
 

# 结论

 
处理大型数据集并不需要专家级别的技能。以下是我们讨论过的技术的快速总结: 

技术 何时使用
分块 用于聚合、筛选以及处理无法放入 RAM 的数据。
列选择 当只需要宽数据集中的几列时。
数据类型优化 加载后始终执行;以节省内存。
分类类型 用于重复值多的文本列(类别、州等)。
读取时筛选 当你只需要一部分行时。
Dask 用于非常大的数据集,或当你需要并行处理时。
采样 在开发和探索阶段。

 

第一步是同时了解你的数据和你的任务。在大多数情况下,结合使用分块处理和智能的列选择就能解决 90% 的问题。

随着你的需求增长,可以转向更先进的工具,如 Dask,或者考虑将数据转换为更高效的文件格式,如 ParquetHDF5

现在就开始着手处理那些海量数据集吧。祝你分析愉快!
 
 

Bala Priya C 是来自印度的开发人员和技术作家。她喜欢在数学、编程、数据科学和内容创作的交叉点工作。她的兴趣和专业领域包括 DevOps、数据科学和自然语言处理。她喜欢阅读、写作、编码和咖啡!目前,她正致力于通过撰写教程、操作指南、观点文章等内容来学习并与开发者社区分享她的知识。Bala 还负责创建引人入胜的资源概述和编码教程。




🚀 想要体验更好更全面的AI调用?

欢迎使用青云聚合API,约为官网价格的十分之一,支持300+全球最新模型,以及全球各种生图生视频模型,无需翻墙高速稳定,文档丰富,小白也可以简单操作。

0

评论区