如何用Pandas高效处理Python大型数据集?求性能优化方案
Pandas 内部优化技巧
- 只加载必要列:读取CSV时用
usecols参数指定仅需要的列(比如你的场景只需要column_name、another_column以及要聚合的数值列),减少内存占用和IO时间:required_cols = ['column_name', 'another_column', 'value_col'] df = pd.read_csv('large_dataset.csv', usecols=required_cols) - 优化字符串列类型:如果
another_column是字符串类型且重复值多,转为category类型,分组操作会基于整数编码执行,大幅提速:df['another_column'] = df['another_column'].astype('category') - 用
query()替代布尔索引:query()基于Numexpr引擎,执行向量化运算,比传统布尔索引更快,尤其适合复杂过滤条件:filtered = df.query('column_name > @threshold_value') - 分块处理时的增量聚合:不要单纯分块加载,而是对每个块先执行过滤+聚合,最后合并结果再做一次聚合,避免全量数据驻留内存:
chunk_size = 100000 agg_results = [] for chunk in pd.read_csv('large_dataset.csv', chunksize=chunk_size, usecols=required_cols): chunk_filtered = chunk[chunk['column_name'] > threshold_value] chunk_agg = chunk_filtered.groupby('another_column').mean(numeric_only=True) agg_results.append(chunk_agg) # 合并后再次聚合得到最终结果 final_result = pd.concat(agg_results).groupby(level=0).mean() - 指定
numeric_only参数:分组聚合时加上numeric_only=True,避免Pandas检查非数值列,节省额外开销:result = filtered.groupby('another_column').mean(numeric_only=True)
替代库方案
如果Pandas本身优化后仍达不到预期,试试这些专为大数据场景设计的库:
- Dask DataFrame:API与Pandas高度兼容,自动利用多核CPU并行处理,支持分块计算,无需修改太多代码:
import dask.dataframe as dd ddf = dd.read_csv('large_dataset.csv', usecols=required_cols) filtered = ddf[ddf['column_name'] > threshold_value] result = filtered.groupby('another_column').mean().compute() - Vaex:基于内存映射技术,无需将全量数据加载到内存,支持延迟计算,处理超大数据集时内存压力极小:
import vaex df = vaex.read_csv('large_dataset.csv') filtered = df[df.column_name > threshold_value] result = filtered.groupby('another_column').mean() - PySpark:适合超大规模分布式处理场景,如果你后续数据量持续增长,PySpark可以利用集群资源并行计算:
from pyspark.sql import SparkSession spark = SparkSession.builder.appName("LargeDataset").getOrCreate() df = spark.read.csv('large_dataset.csv', header=True, inferSchema=True) filtered = df.filter(df.column_name > threshold_value) result = filtered.groupBy('another_column').mean().toPandas()
通用最佳实践
- 提前清理数据:加载数据前先检查并剔除无关行/列,避免无效计算。
- 利用向量化运算:避免在Pandas中使用逐行循环(比如
apply()),优先用内置的向量化函数。 - 使用更快的文件格式:将CSV转为Parquet或Feather格式,这些格式支持列存储、压缩和类型保留,读取和处理速度远快于CSV:
# 转存为Parquet df.to_parquet('large_dataset.parquet') # 后续读取 df = pd.read_parquet('large_dataset.parquet')
内容的提问来源于stack exchange,提问作者hotnoob
相关产品推荐
相关产品推荐

