Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/291.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
PySpark-Spark数据帧数组与Python列表不同吗?_Python_Apache Spark_Dataframe_Pyspark_Apache Spark Sql - Fatal编程技术网

PySpark-Spark数据帧数组与Python列表不同吗?

PySpark-Spark数据帧数组与Python列表不同吗?,python,apache-spark,dataframe,pyspark,apache-spark-sql,Python,Apache Spark,Dataframe,Pyspark,Apache Spark Sql,如果我有一个SparkDataFrame包含arrays,我可以通过一个UDF在这些数组上使用Python列表方法吗?如何将Spark数据帧数组转换为Python列表 下面是一个示例,其中包含一些UDF。我不知道为什么使用max有效,但使用len无效。最后,我想用原始数组列中的采样值创建一个新列。这也得到了一个错误,期待两个参数,奖金点,如果你可以帮助 我有以下SparkDataFrame: from pyspark.sql.functions import udf from pyspark.s

如果我有一个Spark
DataFrame
包含
arrays
,我可以通过一个UDF在这些数组上使用Python列表方法吗?如何将Spark
数据帧
数组
转换为Python列表

下面是一个示例,其中包含一些UDF。我不知道为什么使用max有效,但使用
len
无效。最后,我想用原始数组列中的采样值创建一个新列。这也得到了一个错误,期待两个参数,奖金点,如果你可以帮助

我有以下Spark
DataFrame

from pyspark.sql.functions import udf
from pyspark.sql import Row
from pyspark.sql.types import StringType
from pyspark.sql.types import IntegerType
from pyspark.sql.types import ArrayType
import random

df = sc.parallelize([Row(name='Joe',scores=[1.0,2.0,3.0]),
Row(name='Mary', scores=[3.0]),
Row(name='Mary', scores=[4.0,7.1])]).toDF()
>>> df.show()
+----+---------------+
|name|         scores|
+----+---------------+
| Joe|[1.0, 2.0, 3.0]|
|Mary|          [3.0]|
|Mary|     [4.0, 7.1]|
+----+---------------+
>>> df
DataFrame[name: string, scores: array<double>]
def sampleWithReplacement(listIn,samples):
    tempList = array()
    count=0
    while (count<samples):
        tempList.append(random.sample(listIn,1)[0])
        count=count+1
    return tempList

def maxArray(listIn):
    return max(listIn)

def lenArray(listIn):
    return len(listIn)
sampUDF=udf(sampleWithReplacement,ArrayType())
maxUDF=udf(maxArray,IntegerType())
lenUDF=udf(lenArray,IntegerType())

>>> df.withColumn("maxCol",maxUDF(df.scores)).show()
+----+---------------+------+
|name|         scores|maxCol|
+----+---------------+------+
| Joe|[1.0, 2.0, 3.0]|  null|
|Mary|          [3.0]|  null|
|Mary|     [4.0, 7.1]|  null|
+----+---------------+------+

>>> df.withColumn("maxCol",lenUDF(df.scores)).show()
+----+---------------+------+
|name|         scores|maxCol|
+----+---------------+------+
| Joe|[1.0, 2.0, 3.0]|     3|
|Mary|          [3.0]|     1|
|Mary|     [4.0, 7.1]|     2|
+----+---------------+------+
从pyspark.sql.functions导入udf
从pyspark.sql导入行
从pyspark.sql.types导入StringType
从pyspark.sql.types导入IntegerType
从pyspark.sql.types导入ArrayType
随机输入
df=sc.parallelize([Row(name='Joe',scores=[1.0,2.0,3.0]),
行(name='Mary',分数=[3.0]),
行(name='Mary',分数=[4.0,7.1]))。toDF()
>>>df.show()
+----+---------------+
|姓名|分数|
+----+---------------+
|乔|[1.0,2.0,3.0]|
|玛丽|[3.0]|
|玛丽|[4.0,7.1]|
+----+---------------+
>>>df
DataFrame[名称:字符串,分数:数组]
def样本替换(列表,样本):
templast=array()
计数=0
while(count>>df.withColumn(“maxCol”,maxUDF(df.scores)).show()
+----+---------------+------+
|姓名|分数|马克斯科尔|
+----+---------------+------+
|乔|[1.0,2.0,3.0]|空|
|玛丽|[3.0]|零|
|玛丽|[4.0,7.1]|零|
+----+---------------+------+
>>>df.withColumn(“maxCol”,lenUDF(df.scores)).show()
+----+---------------+------+
|姓名|分数|马克斯科尔|
+----+---------------+------+
|乔|[1.0,2.0,3.0]| 3|
|玛丽|[3.0]| 1|
|玛丽|[4.0,7.1]| 2|
+----+---------------+------+

TL;DR当您有选择时,始终首选内置函数而不是
udf
。要计算长度,请使用
大小
(别名为
长度)
方法:

from pyspark.sql.functions import length, size 

df.withColumn("len", size("scores"))
对于小型阵列,您可以尝试

from pyspark.sql.functions import sort_array

df.withColumn("max", sort_array("scores", False)[0])
当然,对于大型收藏来说,这不是一个好的选择

Spark数据帧数组与Python列表不同吗

在内部,它们是不同的,因为有Scala对象。在
udf
中访问时,会有简单的Python列表。那么,出了什么问题

让我们看一下类型。
scores
列是
array
。当转换为Python类型时,会产生一个
列表[float]
。当调用
max
时,输出上会出现一个
float

但是,您将返回类型声明为
IntegerType
。因为
float
无法转换为整数精度损失结果未定义,因此您将得到
NULL
。返回类型的正确选择是
DoubleType
FloatType

maxf = udf(lambda xs: max(xs), FloatType())
maxd = udf(lambda xs: max(xs), DoubleType())

(sc
    .parallelize([("Joe", [1.0, 2.0, 3.0])])
    .toDF(["name", "scores"])
    .select("*", maxf("scores"), maxd("scores")))
结果:

+----+---------------+----------------+----------------+
|姓名|分数|(分数)|(分数)|
+----+---------------+----------------+----------------+
|乔|[1.0,2.0,3.0]| 3.0 | 3.0|
+----+---------------+----------------+----------------+
和模式:

根目录
|--名称:字符串(nullable=true)
|--分数:数组(可空=真)
||--元素:双精度(containsnall=true)
|--(分数):浮动(可空=真)
|--(分数):双倍(可为空=真)

您是否知道如何将这种数组转换为字符串,而不必像
org.apache.spark.sql.catalyst.expressions那样离开字段。UnsafeArrayData@xxxx
?将其转换为包含以“,”分隔的元素的字符串应该是完美的。