如何在Spark(Python)中对行对象的字段排序
我正在Spark中创建行对象。我不希望我的字段按字母顺序排列。但是,如果我执行以下操作,它们将按字母顺序排列如何在Spark(Python)中对行对象的字段排序,python,apache-spark,pyspark,apache-spark-sql,pyspark-sql,Python,Apache Spark,Pyspark,Apache Spark Sql,Pyspark Sql,我正在Spark中创建行对象。我不希望我的字段按字母顺序排列。但是,如果我执行以下操作,它们将按字母顺序排列 row = Row(foo=1, bar=2) 然后创建一个对象,如下所示: Row(bar=2, foo=1) 然后,当我在这个对象上创建一个dataframe时,列的顺序将是bar优先,foo第二,而我更希望是相反的 我知道我可以使用“_1”和“_2”(分别表示“foo”和“bar”),然后分配一个模式(使用适当的“foo”和“bar”名称)。但是有什么方法可以阻止Row对象对它
row = Row(foo=1, bar=2)
然后创建一个对象,如下所示:
Row(bar=2, foo=1)
然后,当我在这个对象上创建一个dataframe时,列的顺序将是bar优先,foo第二,而我更希望是相反的
我知道我可以使用“_1”和“_2”(分别表示“foo”和“bar”),然后分配一个模式(使用适当的“foo”和“bar”名称)。但是有什么方法可以阻止Row对象对它们进行排序吗?Spark>=3.0 字段排序已通过(删除PySpark SQL行创建中字段的排序)删除 导出),当设置以下环境变量时,传统模式除外:
PYSPARK_ROW_FIELD_SORTING_ENABLED=true
火花<3.0
但是有没有办法防止Row对象对它们进行排序
没有。对于确定性行为,排序是必需的,因为Python 3.6之前的版本不保留关键字参数的顺序
只需使用普通元组:
rdd = sc.parallelize([(1, 2)])
并将模式作为参数传递给(不要混淆):
或createDataFrame
:
from pyspark.sql.types import *
spark.createDataFrame(rdd, ["foo", "bar"])
# With full schema
schema = StructType([
StructField("foo", IntegerType(), False),
StructField("bar", IntegerType(), False)])
spark.createDataFrame(rdd, schema)
您还可以使用namedtuples
:
from collections import namedtuple
FooBar = namedtuple("FooBar", ["foo", "bar"])
spark.createDataFrame([FooBar(foo=1, bar=2)])
最后,您可以按选择对列进行排序:
sc.parallelize([Row(foo=1, bar=2)]).toDF().select("foo", "bar")
发件人:
行还可以用于创建另一个类似行的类,然后可以用于创建行对象
在这种情况下,将保存列的顺序:
>>> FooRow = Row('foo', 'bar')
>>> row = FooRow(1, 2)
>>> spark.createDataFrame([row]).dtypes
[('foo', 'bigint'), ('bar', 'bigint')]
如何对原始模式进行排序以匹配RDD的字母顺序:
schema_sorted = StructType()
structfield_list_sorted = sorted(df.schema, key=lambda x: x.name)
for item in structfield_list_sorted:
schema_sorted.add(item)
如果我有一个嵌套的行对象呢?行(foo=(行(foo1=1,bar1=2))使用元组并提供模式。好的。谢谢!这就是我目前正在做的。我问这个问题的唯一原因是因为我正在构造一个非常复杂的(嵌套、数组等)object.toDF([list:str])
在Spark 2.4.1上对我不起作用。我必须RDD.toDF()。选择(list:str)
确实有效。但在这种情况下,您将失去传递命名参数的能力。foorw(bar=2,foo=1)
将失败。
schema_sorted = StructType()
structfield_list_sorted = sorted(df.schema, key=lambda x: x.name)
for item in structfield_list_sorted:
schema_sorted.add(item)