Python 将自定义函数应用于DataFrame数组类型的列
我有一个dataframe,它有一个名为“counts”的列,我想对该列的每个元素(即每个数组)应用一个自定义函数do_something。我不想修改dataframe,我只想对列计数执行单独的操作。列的所有数组都具有相同的大小Python 将自定义函数应用于DataFrame数组类型的列,python,pyspark,spark-dataframe,rdd,Python,Pyspark,Spark Dataframe,Rdd,我有一个dataframe,它有一个名为“counts”的列,我想对该列的每个元素(即每个数组)应用一个自定义函数do_something。我不想修改dataframe,我只想对列计数执行单独的操作。列的所有数组都具有相同的大小 +----------------------+---------------------------------------+ |id| counts| +----------------------+--------------------
+----------------------+---------------------------------------+
|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以形成列。因此,我认为,每一行都将有作为独立列的内部列表,并且行计数没有变化。