Python 将自定义函数应用于DataFrame数组类型的列

Python 将自定义函数应用于DataFrame数组类型的列,python,pyspark,spark-dataframe,rdd,Python,Pyspark,Spark Dataframe,Rdd,我有一个dataframe,它有一个名为“counts”的列,我想对该列的每个元素(即每个数组)应用一个自定义函数do_something。我不想修改dataframe,我只想对列计数执行单独的操作。列的所有数组都具有相同的大小 +----------------------+---------------------------------------+ |id| counts| +----------------------+--------------------

我有一个dataframe,它有一个名为“counts”的列,我想对该列的每个元素(即每个数组)应用一个自定义函数do_something。我不想修改dataframe,我只想对列计数执行单独的操作。列的所有数组都具有相同的大小

+----------------------+---------------------------------------+
|id|              counts|
+----------------------+---------------------------------------+
|1|          [8.0, 2.0, 3.0|
|2|          [1.0, 6.0, 3.0|                
+----------------------+---------------------------------------+
当我尝试这一点时:

df.select('counts').rdd.foreach(lambda x: do_something(x))
即使我在没有lambda的情况下尝试,也会出现同样的错误

它在上面的线路上出现故障

Py4JJavaError回溯最近的调用 最后的 -->1 df.选择“计数”。rdd.foreachlambda x:do_something x

/foreachself中的usr/hdp/2.5.3.0-37/spark/python/pyspark/rdd.py,f 745外汇 746返回iter[] ->747 self.mapPartitionsprocessPartition.count强制评估 748 749 def foreachPartitionself,f:

/countself 1002中的usr/hdp/2.5.3.0-37/spark/python/pyspark/rdd.py 3 1003 ->1004返回self.mapPartitionslambda i:[sum1 for u in i]。求和1005 1006 def statself:

/sumself中的usr/hdp/2.5.3.0-37/spark/python/pyspark/rdd.py 993 6.0 994 ->995返回self.mapPartitionslambda x:[sumx].fold0,operator.add 996 997 def countself:

/foldself中的usr/hdp/2.5.3.0-37/spark/python/pyspark/rdd.py, 零值 867提供给每个分区的零值与提供的零值是唯一的 868到最后的reduce通话 ->869 VAL=self.mapPartitionsfunc.collect 870返回还原值、VAL、零值 871

/collectself中的usr/hdp/2.5.3.0-37/spark/python/pyspark/rdd.py 769 770,将SCCallSiteSyncself.context作为css: ->771 port=self.ctx.\u jvm.PythonRDD.collectAndServeself.\u jrdd.rdd 772返回列表\u从\u socketport、self.\u jrdd\u反序列化程序加载\u 773

/usr/hdp/2.5.3.0-37/spark/python/lib/py4j-0.9-src.zip/py4j/java_gateway.py 在callself中,*args 811 answer=self.gateway\u client.send\u命令 812返回值=获取返回值 ->813应答,self.gateway\u客户端,self.target\u id,self.name 814 815对于临时参数中的临时参数:

/deco*a中的usr/hdp/2.5.3.0-37/spark/python/pyspark/sql/utils.py, **千瓦 43 def装饰*a,**千瓦: 44尝试: -->45返回f*a,**千瓦 46除py4j.protocol.Py4JJavaError外,错误为e: 47 s=e.java_exception.toString

/usr/hdp/2.5.3.0-37/spark/python/lib/py4j-0.9-src.zip/py4j/protocol.py 在get_return_valueanswer、gateway_client、target_id、name中 306 raise PY4JJAVA错误 307调用{0}{1}{2}时出错。\n。 ->308 formattarget_id、、名称、值 309其他: 310升起Py4JError

尽管所有输入数组的大小都相同

big_list=[]
def do_something(i_array):
    outputs = custom_library(i_array) # takes as input an array and returns 3 new lists
    big_list.extend(outputs)
您的UDF修改python对象,即:

在dataframe外部,即使函数工作,您也无法访问该值,因为您没有将其返回到dataframe的行中 巨大,它的元素数至少是数据帧中行数的三倍 您可以尝试这样做:

def do_something_数组: 输出=自定义\u库i\u数组 返回输出 将pyspark.sql.functions作为psf导入 do_something_udf=psf.udfdo_something,ArrayTypeArrayTypeDoubleType DoubleType或您返回的任何类型

df.withcolumn输出,psf.explodedo\u something\u udfcount
您将有三倍于df的行数

您需要在每个数组上执行的操作。让我们从错误消息开始:此错误发生在哪里?顺便说一下,你们可能不需要lambda,只要把dou_当作论点来讨论就行了@Uvar即使没有lambda我也能得到同样的效果error@Suresh我需要获取列的每个数组,并将其与函数do_something一起使用,以创建一个新的大列表_list@Vas当然是这样,功能没有任何变化除了explode,我们可以索引do_something_udf返回的wrappedArray以形成列。因此,我认为,每一行都将有作为独立列的内部列表,并且行计数没有变化。