from pyspark.sql import Row
一个Row对象是不可变的。它可以转换为Python字典然后变异然后返回到Row对象。有没有办法制作一个可变或变异的副本,而不转换为字典并返回行?
在mapPartitions中运行的函数中需要这样做。
答案 0 :(得分:0)
根据您的实际用例,一种可能性就是从现有用户创建一个新的Row对象。
from pyspark.sql import Row
R = Row('a', 'b', 'c')
r = R(1,2,3)
假设我们要将a
更改为3
r
,从r
创建一个新的Row对象:
R(3, r.b, r.c)
# Row(a=3, b=2, c=3)
虽然r
仍然是:
r
# Row(a=1, b=2, c=3)
答案 1 :(得分:0)
以下是制作变异副本的动态解决方案:
from pyspark.sql import Row
def copy(row, **kwargs):
dict = {}
for attr in list(row.__fields__):
dict[attr] = row[attr]
for key, value in kwargs.items():
dict[key] = value
return Row(**dict)
row = Row(name="foo", age=45)
print(row) #Row(age=45, name='foo')
new_row = copy(row, name="bar")
print(new_row) #Row(age=45, name='bar')
答案 2 :(得分:0)
row.asDict()
和**dict
都不会保留字段的顺序。请注意,在python 3.6+中,这可能会改变。见PEP 468
与@hahmed所说的相似。这会动态创建一个带有与传入的行相同的模式的变异行BUT。
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)