web-dev-qa-db-ja.com

RowオブジェクトのフィールドをSpark(Python)で並べ替えるにはどうすればよいですか?

SparkでRowオブジェクトを作成しています。フィールドをアルファベット順に並べたくありません。ただし、以下を行うとアルファベット順に並べられます。

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

次に、次のようなオブジェクトを作成します。

Row(bar=2, foo=1)

次に、このオブジェクトにデータフレームを作成すると、列の順序が最初にbarになり、次にfooになります。これを逆にしたい場合は、.

「_1」と「_2」(それぞれ「foo」と「bar」)を使用してから、スキーマ(適切な「foo」と「bar」の名前)を割り当てることができることはわかっています。しかし、Rowオブジェクトがそれらを順序付けないようにする方法はありますか?

13
rye

しかし、Rowオブジェクトがそれらを順序付けないようにする方法はありますか?

ありません。 kwargs引数を指定すると、名前でソートされます 。 Python 3.6より前では、キーワード引数の順序が保持されないため、決定論的な動作には並べ替えが必要です。

プレーンタプルを使用するだけです。

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")
10
zero323

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

から ドキュメント

Rowは、クラスのような別のRowを作成するためにも使用でき、次にRowオブジェクトを作成するために使用できます。

この場合、列の順序が保存されます。

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