Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在具有非恒定帧大小的Spark中应用窗口功能_Python_Apache Spark_Pyspark_Window Functions - Fatal编程技术网

Python 在具有非恒定帧大小的Spark中应用窗口功能

Python 在具有非恒定帧大小的Spark中应用窗口功能,python,apache-spark,pyspark,window-functions,Python,Apache Spark,Pyspark,Window Functions,我的问题 我目前在使用Spark窗口功能时遇到困难。我正在使用Spark(通过pyspark)版本1.6.3(关联的Python版本2.6.6)。我运行一个pyspark shell实例,该实例自动将HiveContext初始化为我的sqlContext 我想用窗口函数进行滚动求和。我的问题是窗框不是固定的:这取决于我们考虑的观察结果。更具体地说,我通过一个名为rank\u id的变量对数据进行排序,并希望对索引$x+1$和$2x-1$之间的任何索引为$x$的观测值进行滚动求和。因此,我的范围必

我的问题

我目前在使用Spark窗口功能时遇到困难。我正在使用Spark(通过pyspark)版本
1.6.3
(关联的Python版本
2.6.6
)。我运行一个pyspark shell实例,该实例自动将
HiveContext
初始化为我的
sqlContext

我想用
窗口
函数进行滚动求和。我的问题是窗框不是固定的:这取决于我们考虑的观察结果。更具体地说,我通过一个名为
rank\u id
的变量对数据进行排序,并希望对索引$x+1$和$2x-1$之间的任何索引为$x$的观测值进行滚动求和。因此,我的
范围必须取决于
rank\u id
变量值

重要的一点是,我不想收集数据,因此不能使用任何类似于
numpy
(我的数据有很多观察值)

可复制示例

from pyspark.mllib.random import RandomRDDs
import pyspark.sql.functions as psf
from pyspark.sql.window import Window

# Reproducible example
data = RandomRDDs.uniformVectorRDD(sc, 15, 2)
df = data.map(lambda l: (float(l[0]), float(l[1]))).toDF()
df = df.selectExpr("_1 as x", "_2 as y")

#df.show(2)
#+-------------------+------------------+                                        
#|                  x|                 y|
#+-------------------+------------------+
#|0.32767742062486405|0.2506351566289311|
#| 0.7245348534550357| 0.597929853274274|
#+-------------------+------------------+
#only showing top 2 rows

# Finalize dataframe creation
w = Window().orderBy("x")
df = df.withColumn("rank_id", psf.rowNumber().over(w)).sort("rank_id")
#df.show(3)
#+--------------------+--------------------+-------+                             
#|                   x|                   y|rank_id|
#+--------------------+--------------------+-------+
#|0.016536160706045577|0.009892450530381458|      1|
#| 0.10943843181953838|  0.6478505849227775|      2|
#| 0.13916818312857027| 0.24165348228464578|      3|
#+--------------------+--------------------+-------+
#only showing top 3 rows
固定宽度累积和:没问题

使用
window
函数,我能够在给定数量的索引上运行一个累积和(我在这里使用
rangeBetween
,但在本例中,
rowBetween
可以不加区别地使用)

累计总宽度不固定

我想在索引x+1和2x-1之间求和,其中x是我的行索引。当我尝试将其传递给Spark时(与我们对
orderBy
所做的方式类似,可能这就是问题所在),我得到了以下错误

# Now if I want to make rangeBetween size depend on a variable
w = Window.orderBy('rank_id').rangeBetween('rank_id'+1,2*'rank_id'-1)
回溯(最近一次呼叫最后一次): 文件“”,第1行,在 TypeError:无法连接'str'和'int'对象

我尝试了其他方法,使用SQL语句

# Using SQL expression
df.registerTempTable('tempdf')
df2 = sqlContext.sql("""
   SELECT *, SUM(y)
   OVER (ORDER BY rank_id
   RANGE BETWEEN rank_id+1 AND 2*rank_id-1) AS cumsum
   FROM tempdf;
""")
这一次给了我以下的错误

回溯(最近一次呼叫最后一次): 文件“”,第6行,在 文件“/opt/application/Spark/current/python/pyspark/sql/context.py”,第580行,sql格式 返回数据帧(self.\u ssql\u ctx.sql(sqlQuery),self) 文件“/opt/application/Spark/current/python/lib/py4j-0.9-src.zip/py4j/java_gateway.py”,第813行,调用 文件“/opt/application/Spark/current/python/pyspark/sql/utils.py”,第51行,deco格式 引发分析异常(s.split(“:”,1)[1],stackTrace) pyspark.sql.utils.AnalysisException:u“无法识别windowframeboundary中'rank_id'+'1'附近的输入;第3行位置15”

我还注意到,当我使用
sqlover
子句尝试一个更简单的语句时,我得到了一个类似的错误,这可能意味着我没有正确地将SQL语句传递给Spark

df2 = sqlContext.sql("""
   SELECT *, SUM(y)
   OVER (ORDER BY rank_id
   RANGE BETWEEN -1 AND 1) AS cumsum
   FROM tempdf;
 """)
回溯(最近一次呼叫最后一次): 文件“”,第6行,在 文件“/opt/application/Spark/current/python/pyspark/sql/context.py”,第580行,sql格式 返回数据帧(self.\u ssql\u ctx.sql(sqlQuery),self) 文件“/opt/application/Spark/current/python/lib/py4j-0.9-src.zip/py4j/java_gateway.py”,第813行,调用 文件“/opt/application/Spark/current/python/pyspark/sql/utils.py”,第51行,deco格式 引发分析异常(s.split(“:”,1)[1],stackTrace) pyspark.sql.utils.AnalysisException:u“无法识别windowframeboundary中'-''1''和''附近的输入;第3行位置15”

如何在Spark中使用
window
SQL
语句来解决问题

如何在Spark中使用window或SQL语句来解决问题

TL;DR您不能,或者至少不能以可扩展的方式,满足当前的需求。您可以尝试类似于在RDD上滑动的方法:

我还注意到,当我尝试使用SQLOVER子句执行更简单的语句时,我遇到了一个类似的错误,这可能意味着我没有正确地将SQL语句传递给Spark

df2 = sqlContext.sql("""
   SELECT *, SUM(y)
   OVER (ORDER BY rank_id
   RANGE BETWEEN -1 AND 1) AS cumsum
   FROM tempdf;
 """)
这是不正确的。范围规格要求(
前面的
|
后面的
|
当前行
)规格。此外,不应使用分号:

SELECT *, SUM(x)
OVER (ORDER BY rank_id
RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS cumsum
FROM tempdf
我想在索引x+1和2x-1之间求和,其中x是我的行索引。当我尝试将其传递给Spark时(类似于我们对orderBy所做的方式,可能这就是问题所在),我得到了以下错误

TypeError:无法连接'str'和'int'对象

正如异常所说-您不能对字符串和整数调用
+
。您可能想要专栏:

from pyspark.sql.functions import col

.rangeBetween(col('rank_id') + 1,  2* col('rank_id') - 1)
但这是不受支持的。范围必须具有固定大小,并且不能用表达式定义

重要的一点是,我不想收集数据

不带分区的窗口定义

w = Window.orderBy('rank_id').rangeBetween(-1,3)
和收集一样糟糕。所以,即使有解决“动态框架”(带有条件和无界窗口)问题的变通方法,它们在这里也帮不了你