web-dev-qa-db-ja.com

sparkデータフレームの列位置を変更するには?

実際にスキーマを変更するために、データフレーム内の列の位置を変更することが可能かどうか疑問に思っていましたか?

[field1, field2, field3]のようなデータフレームがあり、[field1, field3, field2]を取得したい場合に正確です。

コードを置くことはできません。結合と変換を行った後、宛先テーブルのスキーマに関してこれらの列の一部が誤って配置された、100列のデータフレームで作業しているとします。

1つまたは複数の列を移動する方法、つまり、スキーマを変更する方法は?

27
obiwan kenobi

列名を取得し、必要に応じて並べ替えてから、元のDataFrameでselectを使用して、この新しい順序で新しい列を取得できます。

val columns: Array[String] = dataFrame.columns
val reorderedColumnNames: Array[String] = ??? // do the reordering you want
val result: DataFrame = dataFrame.select(reorderedColumnNames.head, reorderedColumnNames.tail: _*)
50
Tzach Zohar

spark-daria ライブラリには、DataFrameの列の並べ替えを簡単にするreorderColumnsメソッドがあります。

import com.github.mrpowers.spark.daria.sql.DataFrameExt._

val actualDF = sourceDF.reorderColumns(
  Seq("field1", "field3", "field2")
)

reorderColumnsメソッドは、内部で@Rockie Yangのソリューションを使用します。

df1の列の順序をdf2の列の順序と等しくしたい場合は、すべての列をハードコーディングするよりも次のように動作するはずです。

df1.reorderColumns(df2.columns)

spark-daria ライブラリは、列を昇順または降順に並べ替えるsortColumns変換も定義します(シーケンス内のすべての列を指定したくない場合)。

import com.github.mrpowers.spark.daria.sql.transformations._

df.transform(sortColumns("asc"))
5
Powers

他の人がコメントしたように、名前で列をクエリできる場合、順序は関係ないので、なぜこれを行うのか知りたいです。

とにかく、selectを使用すると、スキーマの説明で列が移動したような感覚が得られます。

val data = Seq(
  ("a",       "hello", 1),
  ("b",       "spark", 2)
)
.toDF("field1", "field2", "field3")

data
 .show()

data
 .select("field3", "field2", "field1")
 .show()
5

@Tzach Zoharに比べてわずかに異なるバージョン

val cols = df.columns.map(df(_)).reverse
val reversedColDF = df.select(cols:_*)
5
Rockie Yang