You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将80GB+公共数据库数据导入Python开展EDA及可视化处理

80GB级CSV文件出租车行程数据EDA落地方案

零额外依赖方案:pandas分块增量统计

  • 放弃直接调用pd.read_csv()加载全量文件的思路,给read_csv传入chunksize参数,将文件拆分为若干个可完全加载进内存的小块逐块读取,单块大小建议设为100万-500万行,可根据自身机器可用内存调整,保证单块加载后内存占用不超过可用内存的30%即可,不会触发内核崩溃。
  • 提前初始化EDA需要的统计结果容器,包括数值列的计数、总和、平方和、最值、空值数,分类列的取值频次,按维度聚合的中间结果。每读取一个数据块,就更新对应容器的统计值,全量文件读取完成后,直接基于累计的统计值计算均值、标准差、占比、分组聚合结果即可,全程不需要在内存中留存全量明细数据。
  • 核心参考代码:
import pandas as pd
import numpy as np

# 提前指定需要统计的字段,避免读取无关列浪费内存
numeric_cols = ["trip_seconds", "trip_miles", "fare", "tips", "tolls", "trip_total"]
cat_cols = ["payment_type", "company"]
date_cols = ["trip_start_timestamp", "trip_end_timestamp"]

# 初始化统计容器
numeric_stats = {
    col: {"valid_count":0, "val_sum":0, "val_sq_sum":0, "min_val":np.inf, "max_val":-np.inf, "null_cnt":0} 
    for col in numeric_cols
}
cat_counts = {col:{} for col in cat_cols}
daily_trip_cnt = {}

# 逐块读取
chunk_iter = pd.read_csv(
    "taxi_trips.csv",
    chunksize=2_000_000,
    usecols=numeric_cols+cat_cols+date_cols+["trip_id"], # 只读需要的列,进一步降低内存占用
    parse_dates=date_cols
)

for chunk in chunk_iter:
    # 更新数值列统计值
    for col in numeric_cols:
        col_valid = chunk[col].dropna()
        numeric_stats[col]["valid_count"] += len(col_valid)
        numeric_stats[col]["val_sum"] += col_valid.sum()
        numeric_stats[col]["val_sq_sum"] += (col_valid ** 2).sum()
        numeric_stats[col]["min_val"] = min(numeric_stats[col]["min_val"], col_valid.min())
        numeric_stats[col]["max_val"] = max(numeric_stats[col]["max_val"], col_valid.max())
        numeric_stats[col]["null_cnt"] += chunk[col].isna().sum()
    
    # 更新分类列频次
    for col in cat_cols:
        vcount_dict = chunk[col].value_counts().to_dict()
        for k, v in vcount_dict.items():
            cat_counts[col][k] = cat_counts[col].get(k, 0) + v
    
    # 更新按天聚合的单量
    daily_cnt = chunk.groupby(chunk["trip_start_timestamp"].dt.date)["trip_id"].count().to_dict()
    for d, cnt in daily_cnt.items():
        daily_trip_cnt[d] = daily_trip_cnt.get(d, 0) + cnt

# 所有块读完后,直接基于三个统计容器计算均值、标准差、占比等EDA指标即可
  • 可视化环节直接使用聚合完成的统计结果绘图即可,不需要调用全量明细数据。

低代码量方案:使用外存计算框架替代原生pandas

  • 如果不想手动写分块统计逻辑,直接用Dask DataFrame即可,它的API和pandas保持90%以上的一致性,会自动调度分块计算、利用磁盘做外存,不需要手动管理分块逻辑,代码改动量极小。本地单机器即可运行,不需要搭建分布式集群,安装直接执行pip install dask[dataframe]。
  • 核心参考代码:
import dask.dataframe as dd

# 读取文件,不会立即加载全量数据进内存
ddf = dd.read_csv(
    "taxi_trips.csv",
    usecols=numeric_cols+cat_cols+date_cols+["trip_id"],
    parse_dates=date_cols
)

# 编写和pandas语法一致的统计逻辑,调用compute()才会实际执行计算
fare_mean = ddf["fare"].mean().compute()
pay_type_share = ddf["payment_type"].value_counts(normalize=True).compute()
daily_trips = ddf.groupby(ddf["trip_start_timestamp"].dt.date)["trip_id"].count().compute()
  • 首次读取完成后建议将文件转存为Parquet列式存储格式,80GB的CSV转成Parquet后体积约10GB左右,后续读取、过滤、聚合的速度会比CSV快5-10倍,一劳永逸,转存代码:ddf.to_parquet("taxi_trips_store/"),后续直接读取该路径即可。

细粒度探索方案:分层抽样加载

  • 对于需要观察明细分布、排查异常值、做特征关联分析的场景,不需要使用全量数据,在分块读取阶段按1%-5%的比例分层抽样即可,抽取出的样本量约800MB-4GB,完全可以用pandas直接加载完成常规EDA流程,抽样结果的统计偏差在EDA可接受范围内。
  • 抽样参考代码:
sample_ratio = 0.02
sample_chunks = []
for chunk in pd.read_csv("taxi_trips.csv", chunksize=2_000_000, usecols=numeric_cols+cat_cols+date_cols+["trip_id"], parse_dates=date_cols):
    sample_chunks.append(chunk.sample(frac=sample_ratio))
sample_df = pd.concat(sample_chunks, ignore_index=True)
# 后续可直接对sample_df使用常规pandas逻辑做探索、绘图

不要尝试强行加载全量80GB数据进内存,常规EDA99%的需求都可以通过增量统计、外存计算、抽样三种方式组合覆盖,不会出现内存不足、内核崩溃的问题。

内容的提问来源于stack exchange,提问作者Ashish Padhi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 04:01:23