Vaex 是一个专为处理大规模表格数据集而设计的 Python 库,它的核心优势在于不需要将整个数据集加载到内存中,就能进行高效的数据探索、分析和可视化。与 Pandas 不同,Vaex 使用内存映射(memory mapping)和惰性计算(lazy evaluation)技术,让你可以在普通笔记本电脑上轻松处理数亿行甚至数十亿行的数据。
为什么选择 Vaex?
传统的 Pandas 处理大数据集时,常常因为内存不足而崩溃。Vaex 通过以下方式解决了这个问题:
内存映射:Vaex 直接读取磁盘上的数据文件(如 HDF5、Apache Arrow、Parquet),仅在需要时才将数据读入内存,因此内存占用极低。
惰性计算:当你写下 df[df.x > 5] 这样的过滤操作时,Vaex 并不会立即执行。它只是构建一个计算图,只有在你明确要求结果(如计算平均值、导出数据或绘图)时才会触发实际计算。
虚拟列:你可以像操作普通列一样定义新列,但这些列实际上是表达式,不占用额外内存,直到被使用才会计算。
安装 Vaex
建议使用 pip 在虚拟环境中安装 Vaex 及其核心扩展:
pip install vaex-core vaex-hdf5 vaex-viz vaex-ml
如果你需要处理 Parquet 格式,建议同时安装 pyarrow:
快速入门:打开并探索数据
Vaex 支持打开 HDF5、Arrow、Parquet 和 CSV 文件。其中,HDF5 和 Arrow 格式因为支持内存映射,性能最佳。
import vaex# 打开一个示例数据集(Vaex 自带)df = vaex.example()print(df)
输出会显示数据集的形状和前几行数据,整个过程几乎是瞬时的,因为数据并未真正加载到内存中。
你也可以直接打开自己的文件:
# 打开 Parquet 文件df = vaex.open('path/to/your_dataset.parquet')# 打开 CSV 文件(建议先转换为 HDF5)# df = vaex.from_csv('large_file.csv', convert=True)
查看数据的基本信息:
# 查看列名print(df.column_names)# 查看数据形状print(df.shape) # 返回 (行数, 列数)# 查看列的数据类型print(df.dtypes)
数据操作:过滤、计算与聚合
1. 过滤数据
过滤操作不会立即执行,而是返回一个新的 DataFrame 对象。
# 筛选出距离大于 10 的行long_trips = df[df.trip_distance > 10]# 多重条件筛选premium_trips = df[(df.trip_distance > 5) & (df.fare_amount > 20) & (df.payment_type == 'credit')]
2. 添加虚拟列
使用 df[...] = 表达式 的方式添加新列,这个过程是即时的,且不占用额外内存。
# 添加一个新列,计算收入的对数值df['log_income'] = df.income.log1p()# 添加更复杂的派生特征df['income_per_mile'] = df.fare_amount / (df.trip_distance + 0.01)
3. 分组聚合
Vaex 的分组聚合操作经过高度优化,速度极快。
# 按支付类型分组,计算平均费用和总收入grouped = df.groupby('payment_type', agg={ 'mean_fare': vaex.agg.mean('fare_amount'), 'total_revenue': vaex.agg.sum('total_amount'), 'trip_count': vaex.agg.count()})# 查看结果(此时会触发计算)print(grouped)
4. 统计描述
计算基本统计量时,Vaex 会扫描整个数据集,但速度非常快。
# 计算单列的平均值mean_fare = df.fare_amount.mean()# 同时计算多个统计量stats = { 'mean_fare': df.fare_amount.mean(), 'total_revenue': df.total_amount.sum(), 'max_distance': df.trip_distance.max(),}
5. 去重操作
Vaex 提供了 drop_duplicates 方法来移除重复行。
# 基于所有列去重df_unique = df.drop_duplicates()# 基于特定列去重df_unique = df.drop_duplicates(['column1', 'column2'])
6. 数据框连接
Vaex 支持高效的连接操作,特别适合将聚合后的统计量合并回主数据集。
# 计算每个城市的平均收入city_avg_income = df.groupby('city', agg={'avg_income': vaex.agg.mean('income')})# 将统计量连接回原数据框df = df.join(city_avg_income, on='city', rsuffix='_city_stats')
高性能绘图
Vaex 的可视化模块 vaex.viz 支持快速绘制大规模数据的统计图表,底层使用 Matplotlib 和 WebGL 进行渲染。
# 绘制散点图(热力图)df.viz.heatmap('x', 'y', f='log', limits='99%')# 绘制多个子图df.viz.heatmap([['x', 'y'], ['x', 'z']], title='Face on and edge on', figsize=(10, 4))# 在热力图上叠加向量场mean_vy = df.mean("vy", binby=["y", "z"], shape=32)mean_vz = df.mean("vz", binby=["y", "z"], shape=32)df.viz.heatmap("y", "z")df.viz.quiver(mean_vy, mean_vz)
与机器学习库集成
Vaex 提供了 vaex.ml 模块,可以对特征进行预处理,并与 scikit-learn 无缝集成,实现外存(out-of-core)机器学习。
import vaex.mlfrom vaex.ml.sklearn import Predictorfrom sklearn.linear_model import LogisticRegression# 对类别特征进行标签编码encoder = vaex.ml.LabelEncoder(features=['city'])df = encoder.fit_transform(df)# 对数值特征进行标准化scaler = vaex.ml.StandardScaler(features=['age', 'income', 'trip_distance'])df = scaler.fit_transform(df)# 准备特征列表features = ['age', 'income', 'trip_distance', 'label_encoded_city']# 训练模型model = LogisticRegression(max_iter=250)vaex_model = Predictor(model=model, features=features, target='label', prediction_name='pred')# 拟合和转换vaex_model.fit(df_train)df_test = vaex_model.transform(df_test)# 获取预测结果(转换为 NumPy 数组用于评估)y_true = df_test['label'].to_numpy()y_pred = df_test['pred'].to_numpy()
性能对比:Vaex vs. Pandas
以 5,000 万行的出租车数据集为例:
打开文件:
Vaex:0.02 秒,内存占用 ~0 MB(内存映射)
Pandas:尝试加载全部数据,通常导致内存错误
计算 5 个聚合统计量:
Vaex:0.88 秒
复杂过滤操作:
Vaex:0.05 秒
可以看到,Vaex 在处理海量数据时,在速度和内存效率方面具有压倒性优势。
总结
Vaex 是一个为大数据集设计的高性能 Python 库,它通过内存映射、惰性计算和虚拟列等机制,让你可以在有限的内存资源下,高效地完成数据清洗、探索、可视化和机器学习建模。如果你经常被 Pandas 的内存问题困扰,Vaex 是一个非常值得尝试的替代方案。