繁体   English   中英

如何在 Spark (Python) 中对 Row 对象的字段进行排序

[英]How do I order fields of my Row objects in Spark (Python)

我在 Spark 中创建 Row 对象。 我不希望我的字段按字母顺序排列。 但是,如果我执行以下操作,它们将按字母顺序排列。

row = Row(foo=1, bar=2)

然后它创建一个如下所示的对象:

Row(bar=2, foo=1)

当我然后在这个对象上创建一个数据框时,列顺序将是 bar 首先,foo 其次,当我更喜欢它的时候。

我知道我可以使用“_1”和“_2”(分别用于“foo”和“bar”),然后分配一个模式(使用适当的“foo”和“bar”名称)。 但是有什么办法可以防止 Row 对象对它们进行排序?

火花 >= 3.0

SPARK-29748删除了字段排序删除 PySpark SQL 行创建导出中的字段排序),遗留模式除外,当设置以下环境变量时:

PYSPARK_ROW_FIELD_SORTING_ENABLED=true 

火花 < 3.0

但是有什么办法可以防止 Row 对象对它们进行排序?

没有。 如果您提供kwargs参数将按 name 排序 确定性行为需要排序,因为 3.6 之前的 Python 不保留关键字参数的顺序。

只需使用普通元组:

rdd = sc.parallelize([(1, 2)])

并将模式作为参数传递给RDD.toDF (不要与DataFrame.toDF混淆):

rdd.toDF(["foo", "bar"])

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)])

最后,您可以通过select对列进行排序:

sc.parallelize([Row(foo=1, bar=2)]).toDF().select("foo", "bar")

文档

Row 也可以用来创建另一个 Row 类,然后它可以用来创建 Row 对象

在这种情况下,列的顺序被保存:

>>> 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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM