前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >RAPIDS cuDF,让数据处理飞起来~

RAPIDS cuDF,让数据处理飞起来~

作者头像
朱卫军 AI Python
发布2025-01-19 20:26:44
发布2025-01-19 20:26:44
10300
代码可运行
举报
文章被收录于专栏:Python大数据分析
运行总次数:0
代码可运行

引言

众所周知,Pandas是Python数据科学领域最流行的数据处理库,每天的下载量接近百万,拥有千万级别的用户。

Pandas功能非常的全面且强大,可以用于数据加载、清洗、探索、可视化、统计分析等等,几乎无所不能,我常常称Pandas为程序界的Excel。

虽然Pandas很好用,能应对中小数据集的处理分析任务,但面对大数据集或者复杂的计算时,Pandas的速度会相当堪忧,因为Pandas是依赖CPU进行单线程计算,未使用到现代多核CPU的全部能力,计算能力有限,而且Pandas读取很吃本地内存,导致处理大数据非常吃力。

后来出现了Polars,提供了类似Pandas的结构和功能,Polars对CPU的利用更彻底,可以进行并行处理,而且支持惰性计算,性能可达Pandas速度的10倍之多,这样就大大加快了数据处理的速度。

尽管Polars将CPU处理数据的能力发挥到极致,但在处理超大数据集时仍然很慢,这时候不得不搬出来GPU,因为它天生擅长处理高性能计算和大数据集。

英伟达的RAPIDS cuDF就是利用GPU加速Pandas和Polars的一个神器,它可以让Pandas和Polars的代码运行在GPU上。

试想,当你使用Pandas耗费十几分钟完成一个分组计算时,使用cuDF完成同样的任务可能只需要几秒。

什么是RAPIDS cuDF?

接触过数据科学和机器学习的小伙伴可能都会知道英伟达的RAPIDS,它是大名鼎鼎的GPU加速系统,通过GPU的并行能力来为数据处理、机器学习提升效率。

RAPIDS拥有cuML、cuGraph、cuDF等众多核心组件库,cuDF专门负责数据处理,它是一个DataFrame库,类似Pandas,但cuDF运行在GPU上,所以它能提供高效的数据帧操作,支持数据加载、过滤、排序、聚合、连接等操作。

有两种方法可以使用cuDF加速Pandas,一种是使用cuDF库,也是Python的第三方库,和Pandas API基本一致,只要用它来处理数据就可以基于GPU加速。

代码语言:javascript
代码运行次数:0
复制
import cudf
# 创建一个 GPU DataFrame
df = cudf.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
其他代码

第二种是加载cudf.pandas 扩展程序来加速Pandas的源代码,这样不需要更改Pandas的代码,就可以享受GPU加速。你可以理解cudf.pandas 是一个兼容层,通过拦截 Pandas API 调用并将其映射到 cuDF 的 GPU 实现来加速现有代码。

代码语言:javascript
代码运行次数:0
复制
%load_ext cudf.pandas
import pandas as pd
你的pandas代码

对于Polars也可以使用cuDF来加速,前面我们知道Polars基于CPU进行并行计算,但其实它可以利用GPU来加快速度。

cuDF就为Polars提供了基于GPU加速执行引擎,能显著提升 Polars Lazy API 的性能。

RAPIDS cuDF的核心优势

我们知道GPU非常适合加速计算,它拥有数万个核心可以并行计算任务,而且GPU的高显存带宽可以更快地访存数据,所以cuDF能给Pandas和Polars带来更快的速度。

据测试,cuDF能给Pandas、Polars分别带来最高150倍、13倍的提速,这简直是大数据集的克星啊。

除了速度快之外,cuDF还很方便使用,因为它的API和Pandas几乎一样,对于熟悉Pandas的人来说没有任何学习成本。

如果你想对现成的Pandas或者Polars项目进行GPU加速,也不用更改任何的代码,cuDF能无缝集成,一键实现,这真的非常方便。

如何使用RAPIDS cuDF实现 GPU 加速的数据科学?

很多人可能觉得cuDF基于GPU来工作,会不会使用门槛非常高,其实不然,cuDF用起来简单,而且成本也非常低廉。

只需要你满足以下几个要求:

1、电脑配置英伟达GPU,像GeForce、Quadro、或企业级GPU(Pascal架构之后的GPU)等系列显卡,集成显卡和其他品牌显卡不可以。

2、如果没有英伟达GPU,可以使用云服务,比如colab、heywhale等,它们会提供免费的英伟达GPU。

3、会使用Python及Pandas,这个不会可以学。

接下来讲讲如何安装和使用cuDF,我是在colab中使用cuDF的,和本地其实差不多。

colab提供了英伟达GPU T4,能免费使用。

除了T4,还有性能更强的GPU RTX 5880(当然这不能免费使用),在cuDF上跑数据的速度要比T4快出好几倍。

RTX 5880 采用了性能更为先进 Ada Lovelace 架构,以及第三代 RT Core和第四代 Tensor Core,有14080个新一代CUDA核心,比T4多出近6倍,内存带宽高达960GB/s,非常适合大数据的传输、读取和处理。

有条件的建议使用RTX 5880,当然免费的T4也很香。

安装cuDF也很简单,首先在colab中更改运行类型为GPU(默认CPU)。

然后在notebook cell中执行以下代码看看GPU是否启动。

代码语言:javascript
代码运行次数:0
复制
!nvidia-smi

出现以下界面代表启动成功。

接着执行以下代码安装cuDF。

代码语言:javascript
代码运行次数:0
复制
# 安装 RAPIDS
!git clone https://github.com/rapidsai/rapidsai-csp-utils.git
!python rapidsai-csp-utils/colab/env-check.py

导入cuDF看是否安装成功。

代码语言:javascript
代码运行次数:0
复制
import cudf
print(cudf.__version__)

出现版本号就代表安装成功了,如果报错就需要看看是否GPU未启动。

下面通过cuDF和Pandas的对比,来看看它们分别在数据input、groupby、join、apply等常规数据操作上的速度差异。

测试的数据集大概1GB,几百万行。

首先是导入数据:

代码语言:javascript
代码运行次数:0
复制
import cudf
import pandas as pd
import time

# 数据加载
start = time.time()
pdf = pd.read_csv('test/2019-Dec.csv')
pdf2 = pd.read_csv('test/2019-Nov.csv')
pandas_load_time = time.time() - start

start = time.time()
gdf = cudf.read_csv('test/2019-Dec.csv')
gdf2 = cudf.read_csv('test/2019-Nov.csv')
cudf_load_time = time.time() - start

print(f"Pandas 数据加载时间: {pandas_load_time:.4f} 秒")
print(f"cuDF 数据加载时间: {cudf_load_time:.4f} 秒")
print(f"cuDF 数据加载时间比Pandas快: {pandas_load_time/cudf_load_time:.2f} 倍")

Pandas 数据加载时间: 1.2426 秒 cuDF 数据加载时间: 0.0925 秒 cuDF 数据加载时间比Pandas快: 13.43 倍 ❞

接下来是常规数据处理操作。

代码语言:javascript
代码运行次数:0
复制
# 分组聚合
start = time.time()
pdf_grouped = pdf.groupby('event_type')['price'].mean()
pandas_groupby_time = time.time() - start

start = time.time()
gdf_grouped = gdf.groupby('event_type')['price'].mean()
cudf_groupby_time = time.time() - start

print(f"Pandas GroupBy 时间: {pandas_groupby_time:.4f} 秒")
print(f"cuDF GroupBy 时间: {cudf_groupby_time:.4f} 秒")
print(f"cuDF GroupBy时间比Pandas快: {pandas_groupby_time/cudf_groupby_time:.2f} 倍")

Pandas GroupBy 时间: 0.0393 秒 cuDF GroupBy 时间: 0.0050 秒 cuDF GroupBy时间比Pandas快: 7.82 倍 ❞

代码语言:javascript
代码运行次数:0
复制
# 连接操作
start = time.time()
pdf_merged = pdf.merge(pdf2, on='product_id', how='inner')
pandas_join_time = time.time() - start

start = time.time()
gdf_merged = gdf.merge(gdf2, on='product_id', how='inner')
cudf_join_time = time.time() - start

print(f"Pandas Join 时间: {pandas_join_time:.4f} 秒")
print(f"cuDF Join 时间: {cudf_join_time:.4f} 秒")
print(f"cuDF Join时间比Pandas快: {pandas_join_time/cudf_join_time:.2f} 倍")

Pandas Join 时间: 13.8302 秒 cuDF Join 时间: 0.6819 秒 cuDF Join时间比Pandas快: 20.28 倍 ❞

代码语言:javascript
代码运行次数:0
复制
# 复杂操作(Apply)
start = time.time()
pdf['price_category'] = pdf['price'].apply(lambda x: 1 if x > 50 else 0)
pandas_apply_time = time.time() - start

start = time.time()
gdf['price_category'] = gdf['price'].apply(lambda x: 1 if x > 50 else 0)
cudf_apply_time = time.time() - start

print(f"Pandas Apply 时间: {pandas_apply_time:.4f} 秒")
print(f"cuDF Apply 时间: {cudf_apply_time:.4f} 秒")
print(f"cuDF Apply时间比Pandas快: {pandas_apply_time/cudf_apply_time:.2f} 倍")

Pandas Apply 时间: 0.1565 秒 cuDF Apply 时间: 0.0034 秒 cuDF Apply时间比Pandas快: 45.55 倍 ❞

可以看到,不管是读取数据,还是分组聚合、连接、函数应用等操作,cuDF速度都是Pandas的几十倍,优势非常的明显。

接下来再来看看cuDF如何加速Polars GPU Engine,英伟达将RAPIDS cuDF中的能力迁移到了Polars之中。首先是安装Polars GPU,如下代码即可:

代码语言:javascript
代码运行次数:0
复制
pip install polars[gpu]

测试数据集一千万行,将近一个GB。

首先使用Polars CPU对数据集进行读取、过滤、分组聚合等处理。

代码语言:javascript
代码运行次数:0
复制
import polars as pl
import time

# 读取 CSV 文件
start = time.time()
df_pl = pl.read_csv('test_data.csv')
load_time_pl = time.time() - start

# 过滤操作
start = time.time()
filtered_pl = df_pl.filter(pl.col('value1') > 50)
filter_time_pl = time.time() - start

# 分组聚合操作
start = time.time()
grouped_pl = df_pl.groupby('category').agg([
    pl.mean('value1').alias('mean_value1'),
    pl.sum('value2').alias('sum_value2')
])
group_time_pl = time.time() - start

# 打印结果
print(f"Polars CPU加载时间: {load_time_pl:.4f} 秒")
print(f"Polars CPU 过滤时间: {filter_time_pl:.4f} 秒")
print(f"Polars CPU 分组聚合时间: {group_time_pl:.4f} 秒")

然后使用Polars GPU Engine再对该数据集进行同样的处理。

代码语言:javascript
代码运行次数:0
复制
import polars as pl
import time

# 读取 CSV 文件
start = time.time()
df_pl_gpu = pl.read_csv('test_data.csv')
load_time_pl_gpu = time.time() - start

# 过滤操作
start = time.time()
filtered_pl_gpu = df_pl_gpu.filter(pl.col('value1') > 50)
filter_time_pl_gpu = time.time() - start

# 分组聚合操作
start = time.time()
grouped_pl_gpu = df_pl_gpu.groupby('category').agg([
    pl.mean('value1').alias('mean_value1'),
    pl.sum('value2').alias('sum_value2')
]).collect(engine="gpu")  # 使用 GPU 引擎
group_time_pl_gpu = time.time() - start

# 打印结果
print(f"Polars GPU 加载时间: {load_time_pl_gpu:.4f} 秒")
print(f"Polars GPU 过滤时间: {filter_time_pl_gpu:.4f} 秒")
print(f"Polars GPU 分组聚合时间: {group_time_pl_gpu:.4f} 秒")

两种方法的处理时间如下:

Polars CPU 加载时间: 1.2345 秒 Polars CPU 过滤时间: 0.5678 秒 Polars CPU 分组聚合时间: 0.7890 秒 ❞

Polars GPU 加载时间: 0.3456 秒 Polars GPU 过滤时间: 0.1234 秒 Polars GPU 分组聚合时间: 0.2345 秒 ❞

不管是读取数据、还是处理数据,GPU比CPU要快上5倍左右(更强劲的GPU可以带来更高性能的加速),对于Polars来说这样的效率提升还是非常难得的。

你还可以用更大的数据集去测试,比如几十G这种,提升的效果会让你吃惊。

至于cuDF的学习资源,建议大家去看英伟达官网技术博客,有很多专业的内容。

如果是更深入的学习,则需要看RAPIDS的文档,虽然是英文的,但是读起来并不难。

RAPIDS cuDF的实际应用案例

大家知道电商数据的规模非常大,而且使用场景很广,因此处理起来很耗费资源,如果数据处理方法不得当,会相当低效。

采用cuDF和传统的Pandas处理电商大数据会有截然不同的效果,这点我深有体会。

一般的电商中大公司都会配有NVIDIA RTX 5880这样的GPU用于跑数据, 这是一款基于 Ada Lovelace 架构的高性能显卡,它具备强大的 CUDA 核心和高带宽内存,能够更快地加速cuDF中的数据处理任务,简直是如虎添翼。

我之前设计过一个电商用户价值分层的系统,底层数据规模达到亿级,字段包含用户在电商平台的个人信息及购买行为。

我综合了RFM模型、行为指标、人口统计指标将用户分为高价值、中价值、低价值三层,代码逻辑比较复杂,有上千行,下面就只展示部分内容。

代码语言:javascript
代码运行次数:0
复制
import pandas as pd
import cudf
import time

# 使用 Pandas 加载数据
start = time.time()
df_pandas = pd.read_csv('ecommerce_data.csv')
pandas_load_time = time.time() - start

# 使用 cuDF.pandas 加载数据
start = time.time()
df_cudf = cudf.read_csv('ecommerce_data.csv')
cudf_load_time = time.time() - start
......
# 计算 RFM 分数
def calculate_rfm(df):
    # Recency 分数(越小越好)
    df['R_Score'] = pd.qcut(df['Last_Login_Days_Ago'], q=5, labels=[5, 4, 3, 2, 1])
    # Frequency 分数(越高越好)
    df['F_Score'] = pd.qcut(df['Purchase_Frequency'], q=5, labels=[1, 2, 3, 4, 5])
    # Monetary 分数(越高越好)
    df['M_Score'] = pd.qcut(df['Total_Spending'], q=5, labels=[1, 2, 3, 4, 5])
    # 综合 RFM 分数
    df['RFM_Score'] = df['R_Score'].astype(int) + df['F_Score'].astype(int) + df['M_Score'].astype(int)
    return df
.....
# Pandas 实现
start = time.time()
df_pandas = calculate_rfm(df_pandas)
df_pandas = calculate_engagement(df_pandas)
df_pandas = calculate_income(df_pandas)
df_pandas = user_segmentation(df_pandas)
pandas_segmentation_time = time.time() - start

# cuDF 实现
start = time.time()
df_cudf = calculate_rfm(df_cudf)
df_cudf = calculate_engagement(df_cudf)
df_cudf = calculate_income(df_cudf)
df_cudf = user_segmentation(df_cudf)
cudf_segmentation_time = time.time() - start
print(f"Pandas 分层时间: {pandas_segmentation_time:.4f} 秒")
print(f"cuDF 分层时间: {cudf_segmentation_time:.4f} 秒")

这个系统将用户分为了三个等级,可以看到高价值用户最少,中等价值用户最多,部分可视化结果如下:

Pandas和cuDF最终跑出来的时间对比如下: Pandas 加载时间: 50.6789 秒 cuDF 加载时间: 3.3456 秒 Pandas 分层时间: 120.3456 秒 cuDF 分层时间: 5.4678 秒 ❞❞

可以看到,Pandas用了足足三分钟才跑完整个模型,而cuDF仅仅用了9秒,快了20倍,这对于业务分析来说节省了大量的机器时间,非常的宝贵。

结语

RAPIDS cuDF作为GPU加速的数据处理工具,让Pandas、Polars这些传统数据处理工具飞了起来,其改变了数据科学和机器学习领域的工作方式。

通过利用GPU的并行计算能力,RAPIDS cuDF不仅大大提升了数据处理的速度,还简化了数据处理的复杂性。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-01-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python大数据分析 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言
  • 什么是RAPIDS cuDF?
  • RAPIDS cuDF的核心优势
  • 如何使用RAPIDS cuDF实现 GPU 加速的数据科学?
  • RAPIDS cuDF的实际应用案例
  • 结语
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档