如何制作PySpark行对象的变异副本?

如何制作PySpark行对象的变异副本?,pyspark,spark-dataframe,rdd,Pyspark,Spark Dataframe,Rdd,来自pyspark.sql导入行 行对象是不可变的。它可以转换为Python字典,然后进行变异,然后返回到行对象。有没有一种方法可以在不转换为字典和行的情况下生成可变或变异副本 这是在mapPartitions中运行的函数所需要的。根据您的实际使用情况,一种可能是简单地从现有的行对象创建一个新的行对象 从pyspark.sql导入行 R=行('a','b','c') r=r(1,2,3) 假设我们要将r的a更改为3,在r中创建一个新的行对象: R(3,R.b,R.c) #行(a=3,b=2,c

来自pyspark.sql导入行

行对象是不可变的。它可以转换为Python字典,然后进行变异,然后返回到行对象。有没有一种方法可以在不转换为字典和行的情况下生成可变或变异副本


这是在mapPartitions中运行的函数所需要的。

根据您的实际使用情况,一种可能是简单地从现有的行对象创建一个新的行对象

从pyspark.sql导入行
R=行('a','b','c')
r=r(1,2,3)
假设我们要将
r
a
更改为
3
,在
r
中创建一个新的行对象:

R(3,R.b,R.c)
#行(a=3,b=2,c=3)
r
仍然是:

r
#行(a=1,b=2,c=3)

以下是我提出的制作变异副本的动态解决方案:

从pyspark.sql导入行
def副本(第行,**kwargs):
dict={}
对于列表中的属性(行、字段):
dict[attr]=行[attr]
对于键,kwargs.items()中的值:
dict[键]=值
返回行(**dict)
行=行(name=“foo”,年龄=45岁)
打印(行)#行(年龄=45,姓名='foo')
新建行=复制(行,name=“bar”)
打印(新行)#行(年龄=45,姓名='bar')
行。asDict()和
**dict
都不保留字段的顺序。注意,在Python3.6+中,这可能会改变。看

类似于@hahmed所说的。这将动态创建一个变异的行,但其模式与传入的行相同

from pyspark.sql import Row
from collections import OrderedDict

def copy(row, **kwargs):
    d = OrderedDict(zip(row.__fields__, row)) #note this is not recursive
    for key, value in kwargs.iteritems():
        d[key]=value
    MyRow = Row(row.__fields__)
    return MyRow(*d.values())
如果您需要将数据帧转换为RDD,然后再次将其转换为DF,那么这非常有用

例如

df_schema = df.schema
rdd = df_schema.rdd.map(lambda row: copy(row, field=newvalue))
new_df = spark.createDataFrame(rdd, df_schema)