天天看点

什么是PyODPS DataFrame

最近已经写了几篇有关pyodps dataframe的文章,但是还是有些同学不明白pyodps dataframe是什么,以及能做什么事情。这篇文章,我会做出解释,以及简单介绍一下实现的原理。

首先什么是dataframe,我在以前的文章也解释过,我们可以把它认为是二维表结构。在单机上,数据科学家一般会使用r或者python库pandas来做数据分析,dataframe是它们上广泛使用的数据结构。在dataframe上,我们可以做过滤、列筛选、join、union等等操作。

因此,dataframe也常常拿来和sql做比较。我觉得主要的区别有:

可能每个系统都有自己的sql语法,但是对于dataframe来说,可以把一套语法应用到不同的系统中,也就是说,各个系统上层的dataframe语法可以是一致的。

dataframe可以和本身的实现语言相关,因此能用到语言相关的特性,变量赋值、和语言三方库集成等等都不在话下。

因此从第一点上来说,就能解释为什么我们的pyodps dataframe能在odps和本地上执行了。同样的语法,灵活性很高。

对于pyodps dataframe来说,什么时候数据在maxcompute上执行,什么时候在本地执行呢?这和用户的初始输入有关。当用户用maxcompute表来初始化dataframe的时候,后续计算就会在maxcompute上执行。

比如例子里,我们用一张maxcompute表来初始化,因此后续的计算都是在maxcompute上执行的。而如果用pandas dataframe来初始化,那么后续的计算就是在本地执行。

在odps上计算时,和本地的计算能力是无关的,除非获取最终计算结果,数据也不会放在本地。

对于在odps上的计算,目前来说,我们绝大多数的操作会使用odps sql执行,但有部分情况,我们会使用tunnel执行,以提高执行速度。这些包括:

对原始表筛选字段

非分区表的切片,或分区表不选取分区或者选取前几个分区字段的切片

非分区表取条数总数,或分区表选取分区的条数总数

举个例子,我们的pyodps_iris是个非分区表,以下情况会使用tunnel,而不是转化成sql执行。

可以看到,使用tunnel的计算是很快的。因此,我们可以利用这个特性来从odps上下载少量数据,来利用本地计算来做debug。

wrap为true时,等同于<code>dataframe(iris[:100].to_pandas())</code>。

下面,简单来说下pyodps dataframe的计算原理。

在某种意义上,pyodps dataframe可以认为是dsl(领域特定语言)。在到立即执行的操作(如execute)前,得到的都是一个ast(抽象语法树)。

在交互式环境下,为了方便,我们在repr一个对象时,里面会调用立即执行的方法。因此,我们先把这个选项关掉,来看看执行后会是什么。

现在我们把verbose打开,执行的中间过程会被打印出来,我们可以看到在odps上,目前会把这个ast给compile成odps sql来执行。

而对于本地数据,我们在compile阶段会把ast转化成一个执行dag(有向无环图),在执行阶段,会按照dag的拓扑顺序来执行,得到最终结果。

好了,至此,已经简单说明了pyodps dataframe框架的执行原理。

pyodps还很年轻,期待大家来使用、提feature、贡献代码。

安装方法:pip install pyodps