云服务器价格_云数据库_云主机【优惠】最新活动-搜集站云资讯

云解析_饥饿游戏百度云_限量秒杀

小七 141 0

rquery:R-Spark用户实用的大数据转换

这是winvector的数据科学家和顾问ninazumel和johnmount的客座社区博客。他们分享了如何在Databricks上使用rquery和apachespark在数据库里试试这个笔记本介绍在这个博客中,我们将介绍rquery,一个强大的查询工具,它允许R用户在Databricks上使用apachespark实现强大的数据转换。rquery是基于edgarf.Codd的关系代数的,我们在大数据规模上使用SQL和R包(比如dplyr)的经验。数据转换与Codd关系代数rquery基于对Codds关系代数的理解。Codd的关系代数是描述数据转换和查询语义的形式代数。以前的分层数据库要求将关联表示为函数或映射。Codd将这一要求从函数放宽到关系,允许表表示更强大的关联(例如,允许双向多映射)。Codd的工作允许将最重要的数据转换分解为由一组较小的基本操作组成的序列:选择(行选择)项目(列选择/聚合)笛卡尔积(表联接、行绑定和集合差分)extend(派生列,关键字在Tutorial-D中)。最早也是最常见的Codd代数实现之一就是SQL。形式上,Codd的代数假设表中的所有行都是唯一的;SQL进一步放宽了这一限制,允许使用多个集。rquery是Codd代数的另一个实现,它实现了上述运算符,一些高阶运算符,并强调从右到左的管道表示法。这为Spark用户提供了一种有效工作的额外方法。用于数据转换的SQL与管道如果没有基于管道的运算符表示法,控制Spark的常用方法包括SQL或排序SparkR数据转换。rquery是一种可以与其他方法相结合的补充方法。SQL的一个问题,尤其是对于初学者的SQL程序员来说,它可能有些不直观。SQL将数据转换表示为嵌套函数组合SQL使用一些关系概念作为步骤,其他概念用作修饰符和谓词。例如,假设您有一个关于鸢尾的信息表,您希望找到平均花瓣最宽的物种。在R中,步骤如下:把桌子分成不同的种类计算每种植物的平均花瓣宽度找出花瓣最宽的平均宽度归还适当的物种我们可以在R中使用rqdatatable(rquery的内存实现)来实现:库(rqdatatable)##正在加载所需的包:rquery数据(iris)虹膜%.>%_nse项目(.,groupby=c('Species'),平均花瓣宽度=平均值(花瓣宽度)) %.>%选择你最喜欢的(。,k=1,orderby=c('平均花瓣宽度','物种'),反向=c('平均花瓣宽度')%.>%选择列(.,'物种')##种##1:弗吉尼亚州当然,我们也可以使用dplyr做同样的操作,dplyr是另一个带有Codd风格操作符的R包。rquery有一些优点,我们将在后面讨论。在rquery中,原始表(iris)位于查询的开头,连续的操作应用于前一行的结果。要在SQL中执行等效操作,必须将该操作基本上向后写:选择种从(选择物种,平均值('花瓣宽度'作为平均花瓣宽度从虹膜按物种分组)tmp1其中平均花瓣宽度=max(平均花瓣宽度)/*尽量选择最宽的种类*/按物种排序*/限制1/*只取回一个物种(如果是平手)*/在SQL中,原始表位于最后一个或最内部的SELECT语句中,并从那里嵌套连续的结果。此外,列选择指令位于SELECT语句的开头,而行选择条件(WHERE、LIMIT)和修饰符(GROUP U BY、ORDER U BY)位于语句的末尾,表位于两者之间。因此,数据转换是从查询的内部到外部进行的,这可能很难读,更不用说很难写了。rquery表示通过将数据转换表示为顺序运算符管道而不是嵌套的查询或函数,从而使关系数据库中的数据转换更直观。Spark/R开发者rquery对于使用Spark和R的开发人员来说,rquery提供了许多优势。首先,R开发人员可以在Spark中运行分析和执行数据转换,使用更易于读取(和编写)的顺序管道表示法,而不是嵌套的SQL查询。正如我们上面提到的,dplyr也提供这种功能,但是dplyr与SparkR不兼容,只与sparklyr兼容。rquery兼容SparkR和sparklyr,以及Postgres和其他大型数据存储。此外,dplyr的lazy求值可能会使大型复杂查询的运行和调试复杂化(下面将对此进行详细说明)。rquery的设计首先是数据库,这意味着它是专门为解决通过R在远程数据存储中处理大数据时出现的问题而开发的。rquery保持查询规范和查询执行阶段之间的完全分离,这允许在运行查询之前进行有用的错误检查和一些优化。在对大量数据运行复杂查询时,这一点很有价值;您不希望只在最后一步发现明显错误的情况下运行长查询。rquery在查询规范时检查列名,以确保它们可供使用。它还跟踪表中的哪些列与给定查询有关,并主动发出适当的SELECT语句以缩小所操作的表。由于Spark的列式方向和延迟求值语义,这在Spark上似乎并不重要,但对于其他数据存储来说,这可能是一个关键,如果您出于任何原因(例如试图破坏计算沿袭),这对Spark至关重要,并且在处理传统的面向行的系统时非常有用。而且,一旦我们按比例工作,这种效果甚至会出现在Spark上。这有助于加快查询的速度,这些查询涉及的表太宽,只需要几个列。rquery还提供格式良好的文本以及查询计划的图形表示。此外,可以在执行之前检查生成的SQL查询。例子对于下一个例子,我们假设我们经营一家食品配送公司,我们对客户喜欢哪种菜系(墨西哥菜、中国菜等)感兴趣。我们要按顾客汇总每种菜肴类型(或餐厅类型)的订单数量,并根据他们点的最多的菜来计算出他们最喜欢的菜肴。我们还想看看这种偏好有多强烈,根据他们点的菜中有多少是他们最喜欢的。我们将从一个订单表开始,该表记录了订单id、客户id和餐厅类型。客户ID餐厅类型订单编号客户1印度的1客户1墨西哥人2客户8印度的三客户5美国人4客户9墨西哥人5客户9印度的6要使用rquery处理数据,我们需要Spark集群的rquery句柄。由于rquery与许多不同类型的SQL方言数据存储接口,因此需要一个适配器将rquery函数转换为适当的SQL方言。默认的处理程序假设一个适应DBI的数据库。由于SparkR不适合DBI,所以我们必须使用函数rquery::rquery_db_info()显式定义处理程序。适配器的代码在这里。假设我们已经将处理程序创建为db\hdl。库("rquery")将(db_hdl)#rquery句柄打印到Spark中##[1]"rquery_db_info(is_dbi=FALSE,SparkR,)"假设我们已经在Spark中有了数据,如order\u表。要使用rquery中的表,必须使用函数db_td()生成一个表说明。表描述是表名称和列的记录;db犵td()查询数据库以获取描述。#假设spark_handle中有数据,#作为视图提供SparkR::createOrReplaceTempView(spark_handle,"订单表")#检查视图中的列名table_description=db_td(db_hdl,"订单表")打印(表格描述)##[1]"表格(''order_table`';custID,餐厅类型,orderID)"打印(列名称(表格描述))##[1]"custID""餐厅_type""orderID"现在,我们可以使用rquery的Codd风格的步骤和管道表示法组成必要的处理管道(或运算符树):rquery_pipeline%扩展列以帮助计数project_nse(.,groupby=c("custID","餐厅类型"),total_orders=sum(one))%.>%\sum orders by type,per customer(总订单数=总订单数(一))%。>%\sum orders by type,per customernormalize_cols(,,#normalize the total_order counts)规格化"总订单数",partitionby='custID')%。>%重命名列(.,#重命名列c('分数\订单'='总订单')%。>%选择最常见的菜肴类型k=1,partitionby='custID',orderby=c('fractional_of_orders','restaurant_type'),reverse=c('U阶分数')%。>%重命名\列(.,c('favorite_cuision'='餐厅类型')%。>%选择"列"(.,c('custID',"最喜欢的菜",'分数'u订单')%.>%orderby(.,cols='custID')在执行管道之前,您可以检查它,可以是文本,也可以是操作符图(使用packagediagrammer)。这对于涉及多个表的复杂查询特别有用。rquery\u管道%.>%运行图(.)%。>%DiagrammeR::DiagrammeR(DiagrammeR=,type="grViz")请注意,normalize_cols和pick_top_k步骤被分解为更基本的Codd操作符(例如extend和select_rows节点)。我们还可以通过Databricks用户界面查看Spark的查询计划。