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

时间:2016-02-11 15:33:39

标签: python apache-spark pyspark apache-spark-sql pyspark-sql

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

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

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

Row(bar=2, foo=1)

当我在这个对象上创建一个数据帧时,列顺序将是第一个,第二个是foo,当我更喜欢使用它时。

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

3 个答案:

答案 0 :(得分:10)

  

但有没有办法阻止Row对象对它们进行排序?

没有。 If you provide kwargs arguments will sorted by 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")

答案 1 :(得分:1)

来自documentation

  

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

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

>>> FooRow = Row('foo', 'bar')
>>> row = FooRow(1, 2)
>>> spark.createDataFrame([row]).dtypes
[('foo', 'bigint'), ('bar', 'bigint')]

答案 2 :(得分:1)

如何对原始架构进行排序以匹配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)