如何在Spark(Python)中订购我的Row对象的字段

rye*_*rye 12 python apache-spark apache-spark-sql pyspark pyspark-sql

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

row = Row(foo=1, bar=2)
Run Code Online (Sandbox Code Playgroud)

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

Row(bar=2, foo=1)
Run Code Online (Sandbox Code Playgroud)

当我然后在这个对象上创建一个数据帧时,列顺序将是第一个,第二个是foo,当我更喜欢用它来反过来时.

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

zer*_*323 10

但是有什么方法可以阻止Row对象对它们进行排序吗?

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

只需使用普通元组:

rdd = sc.parallelize([(1, 2)])
Run Code Online (Sandbox Code Playgroud)

并将模式作为参数传递给 RDD.toDF

rdd.toDF(["foo", "bar"])
Run Code Online (Sandbox Code Playgroud)

或者DataFrame.toDF:

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)
Run Code Online (Sandbox Code Playgroud)

您还可以使用createDataFrame:

from collections import namedtuple

FooBar = namedtuple("FooBar", ["foo", "bar"])
spark.createDataFrame([FooBar(foo=1, bar=2)])
Run Code Online (Sandbox Code Playgroud)

最后,您可以按namedtuples以下方式对列进

sc.parallelize([Row(foo=1, bar=2)]).toDF().select("foo", "bar")
Run Code Online (Sandbox Code Playgroud)

  • 无论如何最好这样做.您可以节省架构推断所需的时间并避免某些类别的错误. (3认同)
  • 使用元组并提供架构. (2认同)