PyOdps DataFrame來臨,數據分析從未如此簡單!

jopen 8年前發布 | 18K 次閱讀 數據分析 SQL

PyOdps正式發布 DataFrame框架 (此處應掌聲經久不息),有了它,就像卷福有了花生,比翼雙飛,哦不,如虎添翼。

快過年了,大家一定沒心情看長篇大論的分析文章。作為介紹PyOdps DataFrame的開篇文章,我只說說其用起來爽的地方。其余的部分,從使用、問題到實現原理,我會分文章細說。

如果你不知道什么是 ODPS ,ODPS是阿里云旗下的大數據計算服務。如果不知道是DataFrame什么,它是存在于pandas和R里的數據結構,你可以把它當做是表結構。如果想快速瀏覽PyOdps DataFrame能做什么,可以看我們的 快速開始文檔

讓我們開始吧。

強類型支持

In [4]: from odps.df import DataFrame

In [5]: iris = DataFrame(o.get_table('pyodps_iris'))

In [6]: iris.dtypes Out[6]: odps.Schema { sepallength float64
sepalwidth float64
petallength float64
petalwidth float64
name string
}

In [7]: iris.field_not_exist

AttributeError Traceback (most recent call last) in () ----> 1 iris.field_not_exist

/Users/chine/Workspace/pyodps/odps/df/expr/expressions.pyc in getattr(self, attr) 510 return self[attr] 511 --> 512 raise e 513 514 def output_type(self):

AttributeError: 'DataFrame' object has no attribute 'field_not_exist'</pre>

如果取存在的字段,自然是沒問題啦。

In [11]: iris.sepalwidth.head(5)
|==========================================|   1 /  1  (100.00%)         0s
Out[11]: 
   sepalwidth
0         3.5
1         3.0
2         3.2
3         3.1
4         3.6

有些方法,比如說取平均數,非數字肯定是不能調用的咯。

In [12]: iris['name'].mean()

AttributeError Traceback (most recent call last) in () ----> 1 iris['name'].mean()

/Users/chine/Workspace/pyodps/odps/df/expr/expressions.pyc in getattribute(self, attr) 171 if new_attr in self._get_attr('_args'): 172 return self._get_arg(new_attr) --> 173 raise e 174 175 def _defunc(self, field):

AttributeError: 'Column' object has no attribute 'mean'</pre>

數字類型的字段則可以調用。

In [10]: iris.sepalwidth.mean()
|==========================================|   1 /  1  (100.00%)        27s
3.0540000000000007

操作數據如此簡單

我們常常需要select一個表字段,但是只是不需要一個字段,卻需要寫一堆SQL。在DataFrame API里,調用 exclude 方法就行了。 

In [13]: iris.exclude('name').head(5)
|==========================================|   1 /  1  (100.00%)         0s
Out[13]: 
   sepallength  sepalwidth  petallength  petalwidth
0          5.1         3.5          1.4         0.2
1          4.9         3.0          1.4         0.2
2          4.7         3.2          1.3         0.2
3          4.6         3.1          1.5         0.2
4          5.0         3.6          1.4         0.2

使用DataFrame寫出來的代碼,天然有Python的特點,清晰易懂。某些快捷API,能使得操作更加簡單。

比如我們要取 name 的個數從大到小前10的值分別是多少。

In [16]: iris.groupby('name').agg(count=iris.name.count()).sort('count', ascending=False)[:10]
|==========================================|   1 /  1  (100.00%)        37s
Out[16]: 
              name  count
0   Iris-virginica     50
1  Iris-versicolor     50
2      Iris-setosa     50

直接使用 value_counts 來得更快。

In [17]: iris['name'].value_counts()[:10]
|==========================================|   1 /  1  (100.00%)        34s
Out[17]: 
              name  count
0   Iris-virginica     50
1  Iris-versicolor     50
2      Iris-setosa     50

很多時候,寫一個SQL,我們需要檢查中間結果的執行,就顯得很麻煩,我們常常需要選取中間的SQL來執行,在DataFrame的世界,中間結果賦值一個變量就行了,這都不是事兒。

計算的過程和結果展示

在DataFrame的執行過程中,我們在終端里和IPython notebook里,都會有進度條顯示任務的完成情況。結果的輸出也會有更好的格式化展現,在IPython notebook里會以HTML表格的形式展現。

PyOdps DataFrame來臨,數據分析從未如此簡單!

繪圖集成

DataFrame的計算結果能直接調用plot方法來制作圖表,不過繪圖需要安裝 pandasmatplotlib

In [21]: iris.plot()
|==========================================|   1 /  1  (100.00%)         0s
Out[21]: <matplotlib.axes._subplots.AxesSubplot at 0x10feab610>

PyOdps DataFrame來臨,數據分析從未如此簡單!

導出數據再用excel畫圖,這事兒……咳咳,未來我們還會提供更好的可視化展現,比如提供交互式的圖表。

自定義函數和Lambda表達式

DataFrame支持map方法,想對一個字段調用自定義函數非常方便。

In [30]: GLOBAL_VAR = 3.2

In [31]: def myfunc(x): if x < GLOBAL_VAR: return 0 else: return 1

In [32]: iris['sepalwidth', iris.sepalwidth.map(myfunc).rename('sepalwidth2')].head(5) |==========================================| 1 / 1 (100.00%) 18s Out[32]: sepalwidth sepalwidth2 0 3.5 1 1 3.0 0 2 3.2 1 3 3.1 0 4 3.6 1</pre>

可惜apply和聚合的自定義函數,暫時還不支持,期待吧!

延遲執行

DataFrame API的所有操作并不會立即執行,除非用戶顯式調用 execute 方法或者一些立即執行的方法。在交互式界面下,打印或者repr對象的時候,內部也會調用 execute 方法,方便用戶使用。

執行優化

DataFrame框架在執行前會對整個查詢進行優化,比如連續的projection合并。當用戶查看原始表(或者選取某個分區)時,會使用tunnel來獲取結果。

PyOdps DataFrame的下一步發展

好了,說了這么多,聊一聊我們DataFrame接下來要做的事情,首先,我們會實現多計算后端,包括pandas,當數據量比較小的時候,我們可以使用本地計算,而不需要等待ODPS的調度;其次,DataFrame框架和我們的機器學習部分會有更多的集成,從數據分析,到算法,一氣呵成。

PyOdps非常年輕,才短短幾個月的時間。我們的整個項目,在GitHub上開源。我個人非常希望大家能參與到開源的建設中來,能提個建議也是極好的。所以,我會寫文章詳述我們PyOdps的實現原理,希望大家一起把ODPS建設得更好。

github: https://github.com/aliyun/aliyun-odps-python-sdk

文檔: http://pyodps.readthedocs.org/zh_CN/latest/

</div> </div>

來自: http://qinxuye.me/article/pyodps-dataframe-a-data-analysis-framework/

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!