1. 程式人生 > >PyODPS DataFrame:統一的資料查詢語言

PyODPS DataFrame:統一的資料查詢語言

摘要: 前幾天,PyODPS釋出了0.7版本,這篇文章給大家介紹下PyODPS新版本帶來的重要特性。 之前也有若干篇文章介紹過了,我們PyODPS DataFrame是延遲執行的,在呼叫立即執行的方法,比如execute、persist等之前,都只是構建了表示式。

前幾天,PyODPS釋出了0.7版本,這篇文章給大家介紹下PyODPS新版本帶來的重要特性。

之前也有若干篇文章介紹過了,我們PyODPS DataFrame是延遲執行的,在呼叫立即執行的方法,比如execute、persist等之前,都只是構建了表示式。而真正的執行根據具體的輸入資料,來決定執行的後端。

比如,我們可以根據輸入是pandas DataFrame(本地資料),還是MaxCompute Table(MaxCompute資料)來決定是在本地執行,還是在MaxComput上執行。

In [1]: import pandas as pd

In [2]: pd_df = pd.DataFrame({'a': range(3)})

In [3]: from odps.df import DataFrame

In [4]: df = DataFrame(pd_df)  # 本地資料

In [5]: df.a.sum()
|==========================================|   1 /  1  (100.00%)         0s
3

In [6]: %load_ext odps

In [7]: %enter
Out[7]: <odps.inter.Room at 0
x105951990> In [8]: df = DataFrame(o.get_table('pyodps_iris')) # MaxCompute資料 In [9]: df.sepal_width.sum() |==========================================| 1 / 1 (100.00%) 15s 458.10000000000014

資料庫執行

來到了0.7版本,我們的後端武器庫進一步擴充,現在我們支援Postgresql和MySQL,原則上我們支援所有的主流資料庫,但我們只在這兩個資料庫上做了測試。

我們的資料庫執行後端使用 sqlalchemy 實現,想要執行還需要對應資料庫的driver。

現在,如果DataFrame輸入的資料是sqlalchemy Table,那麼我們就可以使用資料庫後端來執行。

In [24]: mysql_engine = sqlalchemy.create_engine('mysql://root:[email protected]/movielens') 

In [25]: metadata = sqlalchemy.MetaData(bind=mysql_engine)   # 需要繫結engine

In [26]: table = sqlalchemy.Table('top_users', metadata, extend_existing=True, autoload=True)

In [27]: top_users = DataFrame(table)

In [28]: top_users.age.sum()
|==========================================|   1 /  1  (100.00%)         0s
763

對於postgresql也是一樣。 值得注意的是,現在還有部分DataFrame操作,比如自定義函式尚未支援資料庫後端

可以看到,PyODPS DataFrame就是一個統一的資料查詢語言,使用者不需要改寫一行程式碼,就可以根據輸入讓資料在MaxCompute、本地和資料庫上執行,由於DataFrame框架的靈活性,我們甚至還可以擴展出非SQL執行後端的支援。

JOIN或者UNION資料庫和MaxCompute資料

過去 一篇文章 提到過,我們可以join或者union本地和MaxCompute上的資料,這樣的典型場景就是,比如我有個本地excel檔案,我可以輕鬆讀取成本地DataFrame,然後直接就可以和MaxCompute資料進行操作,省去了一大堆麻煩的過程。

現在,我們也同樣可以join 資料庫和MaxCompute上的資料,試想,有一堆使用者資料是在資料庫中進行處理,然後我們無需經過同步資料等繁瑣的過程,我們就可以直接join 資料庫和MaxCompute上的資料,這是何其方便的事情。

比如:

In [29]: ratings = o.get_table('movielens_ratings').to_df()

In [32]: female_top_users = top_users[top_users.sex == 'F']  # MySQL中的資料

In [33]: ratings.join(female_top_users).rating.mean()
|==========================================|   1 /  1  (100.00%)        14s
2.9451170298627924

總結

我們PyODPS一直處在快速迭代的過程中,我們所有所做的努力,都是為了讓大家以更好的體驗來進行資料分析和機器學習。儘管我們很努力,但精力畢竟有限,難免會有bug,會有功能不完善。希望大家能給我們提issue,能貢獻程式碼就更好啦。

釘釘掃碼:
圖片描述