SparkでRowオブジェクトを作成しています。フィールドをアルファベット順に並べたくありません。ただし、以下を行うとアルファベット順に並べられます。
row = Row(foo=1, bar=2)
次に、次のようなオブジェクトを作成します。
Row(bar=2, foo=1)
次に、このオブジェクトにデータフレームを作成すると、列の順序が最初にbarになり、次にfooになります。これを逆にしたい場合は、.
「_1」と「_2」(それぞれ「foo」と「bar」)を使用してから、スキーマ(適切な「foo」と「bar」の名前)を割り当てることができることはわかっています。しかし、Rowオブジェクトがそれらを順序付けないようにする方法はありますか?
しかし、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")
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)
から ドキュメント :
Rowは、クラスのような別のRowを作成するためにも使用でき、次にRowオブジェクトを作成するために使用できます。
この場合、列の順序が保存されます。
>>> FooRow = Row('foo', 'bar')
>>> row = FooRow(1, 2)
>>> spark.createDataFrame([row]).dtypes
[('foo', 'bigint'), ('bar', 'bigint')]