PyOdps在交互式环境下的使用,让探索ODPS数据更容易些

MckinleyXZB 9年前

来自: http://qinxuye.me/article/pyodps-interactive-enhancement/

春节结束了,是时候来些新鲜玩意,让我们来看一些酷的东西。

当当当当:隆重推出PyOdps logo:

好像跑题了,好吧,让我们言归正传。

我们知道Python提供了一个交互式的环境,能够方便探索和试验想法。同时, IPython 是Python交互环境的增强,提供了很多强大的功能;IPython Notebook(现在已经是Jupyter Notebook)则更酷,提供了一个web界面,除了提供交互环境,还是一个记录计算过程的『笔记本』。

PyOdps也提供了一系列在 交互式环境下的增强工具 ,使得探索ODPS数据更方便快捷。

配置ODPS帐号

Python交互环境

同一个环境支持配置若干个ODPS帐号,只需要:

In [1]: from odps.inter import setup    In [2]: setup('**your-access_id**', '**your-access-key**', '**your-project**', endpoint='**your-endpoint**')

此时这个帐号会被配置到一个叫做 default 的我们称之为 room 的地方。以后我们再使用这个帐号只需要: 

In [3]: from odps.inter import enter    In [4]: room = enter()    In [5]: o = room.odps    In [6]: o.get_table('dual')  Out[6]:   odps.Table    name: odps_test_sqltask_finance.`dual`    schema:      c_int_a                 : bigint                c_int_b                 : bigint                c_double_a              : double                c_double_b              : double                c_string_a              : string                c_string_b              : string                c_bool_a                : boolean               c_bool_b                : boolean               c_datetime_a            : datetime              c_datetime_b            : datetime

通过 room 的odps属性,我们可以取到ODPS的入口,这样就可以接着进行ODPS操作了。配置了别的 room 比如叫做myodps,要取到ODPS入口,只需要 enter('myodps').odps 即可。

list_rooms 方法能列出所有的 room 。

In [17]: from odps.inter import list_rooms    In [18]: list_rooms()  Out[18]: ['default', 'meta']

IPython及Jupyter Notebook

PyOdps还提供了IPython插件。首先我们需要加载插件:

In [11]: %load_ext odps    In [14]: %enter  Out[14]:     In [15]: o = _.odps    In [16]: o.get_table('dual')  Out[16]:   odps.Table    name: odps_test_sqltask_finance.`dual`    schema:      c_int_a                 : bigint                c_int_b                 : bigint                c_double_a              : double                c_double_b              : double                c_string_a              : string                c_string_b              : string                c_bool_a                : boolean               c_bool_b                : boolean               c_datetime_a            : datetime              c_datetime_b            : datetime

_ 下划线能取到上一步的结果。

保存常用的ODPS对象

room 除了提供ODPS入口的功能,还能保存常用的ODPS对象。比如,我们能把常用的表起个名字,给保存起来。

In [19]: iris = o.get_table('pyodps_iris')    In [23]: room.store('iris_test', iris, desc='保存测试ODPS对象')    In [28]: room['iris_test']  Out[28]:   odps.Table    name: odps_test_sqltask_finance.`pyodps_iris`    schema:      sepallength           : double            sepalwidth            : double            petallength           : double            petalwidth            : double            name                  : string          In [29]: room.iris_test  Out[29]:   odps.Table    name: odps_test_sqltask_finance.`pyodps_iris`    schema:      sepallength           : double            sepalwidth            : double            petallength           : double            petalwidth            : double            name                  : string

这两种方式都可以取到保存的ODPS对象。如果要列出当前room保存的所有ODPS对象,则可以:

In [30]: room.display()  Out[30]:   default          desc  name                   iris_test  保存测试ODPS对象  iris       安德森鸢尾花卉数据集

也可以使用IPython插件命令:

In [31]: %stores  Out[31]:   default          desc  name                   iris_test  保存测试ODPS对象  iris       安德森鸢尾花卉数据集

要删除某个ODPS对象:

In [32]: room.drop('iris_test')    In [33]: %stores  Out[33]:   default        desc  name                 iris     安德森鸢尾花卉数据集

执行SQL命令

PyOdps提供了 执行SQL的方法 ,但是在交互式环境下却不甚方便。使用PyOdps提供的IPython插件,可以通过sql命令来直接执行。

在执行时,需要配置全局帐号,如果已经使用了 enter 方法或者命令,则已经配置;如果没有,则会尝试enter默认的room;如果这也没有配置,则需要使用 to_global 方法。

In [34]: o = ODPS('**your-access-id**', '**your-secret-access-key**', project='**your-project**', endpoint='**your-end-point**'))    In [35]: o.to_global()

这时我们就可以使用sql命令,单个百分号输入单行SQL,多行SQL使用两个百分号:

In [37]: %sql select * from pyodps_iris limit 5  |==========================================|   1 /  1  (100.00%)         3s  Out[37]:      sepallength  sepalwidth  petallength  petalwidth         name  0          5.1         3.5          1.4         0.2  Iris-setosa  1          4.9         3.0          1.4         0.2  Iris-setosa  2          4.7         3.2          1.3         0.2  Iris-setosa  3          4.6         3.1          1.5         0.2  Iris-setosa  4          5.0         3.6          1.4         0.2  Iris-setosa    In [38]: %%sql     ....: select * from pyodps_iris     ....: where sepallength < 5      ....: limit 5     ....:   |==========================================|   1 /  1  (100.00%)        15s  Out[38]:      sepallength  sepalwidth  petallength  petalwidth         name  0          4.9         3.0          1.4         0.2  Iris-setosa  1          4.7         3.2          1.3         0.2  Iris-setosa  2          4.6         3.1          1.5         0.2  Iris-setosa  3          4.6         3.4          1.4         0.3  Iris-setosa  4          4.4         2.9          1.4         0.2  Iris-setosa

在Jupyter Notebook里,多行SQL会提供语法高亮:

持久化pandas DataFrame为ODPS表

使用 persist 命令即可:

In [42]: import pandas as pd    In [43]: df = pd.read_csv('https://raw.github.com/pydata/pandas/master/pandas/tests/data/iris.csv')    In [48]: %persist df pyodps_iris_test  |==========================================| 150 /150  (100.00%)         0s    In [49]: from odps.df import DataFrame    In [61]: DataFrame(o.get_table('pyodps_iris_test')).head(5)  |==========================================|   1 /  1  (100.00%)         0s  Out[61]:      sepallength  sepalwidth  petallength  petalwidth         name  0          5.1         3.5          1.4         0.2  Iris-setosa  1          4.9         3.0          1.4         0.2  Iris-setosa  2          4.7         3.2          1.3         0.2  Iris-setosa  3          4.6         3.1          1.5         0.2  Iris-setosa  4          5.0         3.6          1.4         0.2  Iris-setosa

其它交互式方面的增强

在交互式环境下,我们repr一个ODPS表的时候,会打印这个表的schema,包括字段注释,省去了查这个表的meta信息。

In [41]: o.get_table('china_stock', project='odpsdemo')  Out[41]:   odps.Table    name: odpsdemo.`china_stock`    schema:      d               : string      # 日期      c               : string      # 股票代码      n               : string      # 股票名称      t_close         : double      # 收盘价      high            : double      # 最高价      low             : double      # 最低价      opening         : double      # 开盘价      l_close         : double      # 昨日收盘价      chg             : double      # 涨跌额      chg_pct         : double      # 涨跌幅      vol             : bigint      # 成交量      turnover        : double      # 成交额    partitions:      code            : string      # 股票代码

当使用sql命令或者使用DataFrame框架计算的时候,在终端或者Jupyter Notebook里都提供一个进度条来方便用户来查看执行进度。

后记

PyOdps现在处于快速迭代阶段,我们所有的开发都是开源的。大家如果需要什么功能,可以给我们提issue( GitHub );也可以直接参与到开发,直接给我们发Pull Request就行啦。

欢迎大家一起来建设PyOdps。

</div>