CPU靠邊站!使用cuDF在GPU加速Pandas

  • 2019 年 10 月 10 日
  • 筆記

前言

使用Pandas Dataframe執行數千甚至數百萬次計算仍然是一項挑戰。你不能簡單的將數據丟進去,編寫Python for循環,然後希望在合理的時間內處理數據。公眾號在此之前的一篇文章專門介紹了一些方法,請點擊查看:

高逼格使用Pandas加速代碼,向for循環說拜拜!

儘管如此,即使加速,Pandas仍然只能在CPU上運行。由大家的CPU通常有8個或更少的核,因此達到的加速是有限的。我們的數據集可能有多達數百萬、數十億甚至數萬億個,8核不足以解決這個問題。

幸運的是,隨着GPU加速在機器學習領域的成功普及,將數據分析庫應用到GPU上有了強大的推動力。cuDF庫就是朝這個方向邁出的一步。

cuDF

cuDF(https://github.com/rapidsai/cudf)是一個基於Python的GPU DataFrame庫,用於處理數據,包括加載、連接、聚合和過濾數據。向GPU的轉移允許大規模的加速,因為GPU比CPU擁有更多的內核。

cuDF的API是Pandas的一面鏡子,在大多數情況下可以直接替代Pandas。這使得數據科學家、分析師和工程師很容易將其集成到他們的工作中。

那麼,你所需做的是把你的Pandas DataFrame轉換成cuDF。cuDF支持Pandas大多數常見的DataFrame操作,因此無需太多學習成本你就可以加速許多常規的Pandas代碼

我們首先安裝庫文件:

下面是我們測試電腦的配置參數:

  • i7–8700k CPU
  • 1080 Ti GPU
  • 32 GB of DDR4 3000MHz RAM
  • CUDA 9.2

獲得GPU加速

我們將加載一個包含隨機數的Big數據集,並比較不同Pandas操作的速度與使用cuDF在GPU上執行相同操作的速度。

首先初始化Dataframes:一個用於Pandas,一個用於cuDF。DataFrame有超過1億個單元格!

import pandas as pd  import numpy as np  import cudf    pandas_df = pd.DataFrame({'a': np.random.randint(0, 100000000, size=100000000),                            'b': np.random.randint(0, 100000000, size=100000000)})    cudf_df = cudf.DataFrame.from_pandas(pandas_df)

在我們的第一個測試中,讓我計算一下 Pandas VS cuDF數據中a變量的平均值需要多長時間。%timeit 命令允許我們在Jupyter計算Python命令的速度。

https://docs.python.org/3.6/library/timeit.html

# Timing Pandas  # Output: 82.2 ms per loop  %timeit pandas_df.a.mean()    # Timing cuDF  # Output: 5.12 ms per loop  %timeit cudf_df.a.mean()

平均運行時間顯示在代碼注釋中。我們得到了將近16倍的加速!

現在,做一些更複雜的事情,比如做一個大合併。將Dataframe本身合併到數據Dataframe的b列上。

這裡的合併是一個非常大的操作,因為Pandas將不得不尋找並匹配公共值,對於一個有1億行的數據集來說,這是一個非常耗時的操作!GPU加速將使這變得容易,因為我們有更多的並行進程可以一起工作。

代碼:

# Timing Pandas  # Output: 39.2 s per loop  %timeit pandas_df.merge(pandas_df, on='b')    # Timing cuDF  # Output: 2.76 s per loop  %timeit cudf_df.merge(cudf_df, on='b')

即使使用i7-8700k CPU,Pandas完成合併平均也需要39.2秒。而cuDF在GPU上只花了2.76秒。14倍的加速!

快去試試吧!

—End—