如何更改spark数据框中的列位置?

时间:2016-06-29 15:55:22

标签: scala apache-spark dataframe apache-spark-sql

我想知道是否可以更改数据框中列的位置,实际上是否可以更改架构?

确切地说,如果我有一个像[field1,field2,field3]这样的数据帧,我想获得[field1,field3,field2]。

非常感谢任何帮助!

感谢。

编辑:

我不能放任何代码。 让我们假设我们正在使用具有一百列的数据框,在一些连接和转换之后,这些列中的一些关于目标表的模式是错误的。 所以我的观点是:如何移动一列或多列,即:如何更改架构?

感谢。

7 个答案:

答案 0 :(得分:46)

您可以获取列名称,然后根据需要重新排序,然后在原始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: _*)

答案 1 :(得分:5)

与@Tzach Zohar比较的微不足道的版本

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

答案 2 :(得分:5)

spark-daria库有reorderColumns方法,可以轻松对DataFrame中的列重新排序。

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

答案 3 :(得分:4)

与其他人评论一样,我很想知道为什么要这样做,因为当您可以按名称查询列时,订单不相关。

无论如何,使用select应该会感觉列已经在架构描述中移动了:

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

data
 .show()

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

答案 4 :(得分:3)

对于任何动态帧,首先将动态帧转换为数据帧以使用标准pyspark函数

data_frame = dynamic_frame.toDF()

现在,使用选择功能操作将列重新排列为新的数据框。

data_frame_temp = data_frame.select(["col_5","col_1","col_2","col_3","col_4"])

答案 5 :(得分:0)

这是在pyspark中可以做的事情:

与MySQL查询一样,您可以重新选择所需的列顺序并将其传递给参数,并返回与传递查询参数相同的顺序。

from pyspark.sql import SparkSession

data = [
    {'id': 1, 'sex': 1, 'name': 'foo', 'age': 13},
    {'id': 1, 'sex': 0, 'name': 'bar', 'age': 12},
]

spark = SparkSession \
    .builder \
    .appName("Python Spark SQL basic example") \
    .getOrCreate()

# init df
df = spark.createDataFrame(data)
df.show()

输出如下

+---+---+----+---+
|age| id|name|sex|
+---+---+----+---+
| 13|  1| foo|  1|
| 12|  1| bar|  0|
+---+---+----+---+

输入您要选择的列位置顺序作为参数

# change columns position
df = df.select(df.id, df.name, df.age, df.sex)
df.show()

输出如下

+---+----+---+---+
| id|name|age|sex|
+---+----+---+---+
|  1| foo| 13|  1|
|  1| bar| 12|  0|
+---+----+---+---+

希望我能为您提供帮助。

答案 6 :(得分:0)

Spark Scala 示例:

假设您有一个数据框 demo_df 并且它具有以下列集:
id, salary, country, city, firstname, lastname
并且你想重新排列它的顺序。

demo_df
demo_df_screenshot

选择所有列并删除要重新排列的列。
我已从列列表中删除了“薪水、国家、城市”列。

val restcols = demo_df.columns.diff(Seq("salary", "country", "city"))

现在根据您的要求重新排列列名称并将其附加或添加到其余列
添加列的示例
val all_cols = Seq($"salary", $"city", $"country") ++: restcols.map(col(_))

现在选择数据框并提供新定义的列列表
demo_df.select(all_cols: _*).show() enter image description here

附加列的示例
val all_cols = restcols.map(col(_)) ++ Seq($"salary", $"city", $"country") demo_df.select(all_cols: _*).show() enter image description here

希望有帮助。快乐编码!!