在数据块中使用Scala或PySpark将大型水平数据框中的一组重复列转置到新的垂直数据框中



这个问题虽然以前似乎已经回答了,但实际上并不是。所有的转置似乎都与一列有关,并将该列中的数据旋转。我想从一组水平列中创建一个垂直表,例如:-

举个例子:-

tbody> <<tr>
MyPrimaryKey Insurer_Factor_1_Name Insurer_Factor_1_Value Insurer_Factor_2_Name Insurer_Factor_2_Code Insurer_Factor_2_Value Insurer_Factor_[n]_Name Insurer_Factor_[n]_Code Insurer_Factor_[n]_Value Insurer_Factor_[n]_Code Insurer_Factor_[n]_Value
xx六边形abcdef - 1234 abcdef123特殊SP12500AW23500ecetera999999

您没有找到它的原因是,没有一个魔术技巧可以将一个"有趣"设计的表移动到一个设计良好的表中。您将不得不手工编写查询代码,要么将行合并到表中,要么选择然后爆炸的数组。

当然,你可能会写一些代码来生成你想要的SQL,但它们真的不是一个很好的功能,神奇地将这个feature格式转换成基于行的格式。

按偏好排序:

重新考虑发送多个文件的决定:如果你只发送多个文件,听起来会节省很多工作。

修改列模式:在列模式中放入一个分隔符(每4列),允许我们查看行。然后我们可以将文件分成几行。使用分隔符

编写自己的自定义数据源:您可以使用现有的文本作为示例,如何编写自己的文本,将每3列解释为一行。

编写一个自定义UDF,将所有列作为参数并返回一个行数组,然后调用该数组来将它们转换为行。这将是缓慢的,所以我给你作为最后的选择。

***警告这会占用很多内存。对于6000行,它将很慢,并且可能会耗尽内存。如果它工作得很好,但我建议你编写自己的数据源,因为这可能是一个更好/更快的策略。

如果你想用UDF做这件事,并且你只对几行做这件事,你可以这样做:

import org.apache.spark.sql._
import org.apache.spark.sql.types._
import org.apache.spark.sql.functions._
/* spark.sql("select * from info").show();
+----+-------+----+
|type|db_type|info|
+----+-------+----+
| bot|  x_bot|   x|
| bot|  x_bnt|   x|
| per|   xper|   b|
+----+-------+----+ */
val schema = ArrayType(new StructType().add("name","string").add("info","string"))
val myUDF = udf((s: Row) => {
Seq( Row( s.get(0).toString, s.get(1).toString ), Row(s.get(2).toString, s.get(2).toString ) )
},schema)
val records = spark.sql("select * from info");
val arrayRecords = records.select( myUDF(struct(records.columns.map(records(_)) : _*)).alias("Arrays") )
arrayRecords.select( explode(arrayRecords("Arrays")).alias("myCol") )
.select( col("myCol.*").show()
+----+-----+
|name| info|
+----+-----+
| bot|x_bot|
|   x|    x|
| bot|x_bnt|
|   x|    x|
| per| xper|
|   b|    b|
+----+-----+
<<ul>
  • Sudo代码/gh>
  • 为行创建schema
  • 创建udf(带模式)(这里我只展示了小的操作,但显然你可以在你的情况下使用更复杂的逻辑)
  • 选择数据,
  • 应用udf,
  • 爆炸数组。
  • 相关内容

    • 没有找到相关文章

    最新更新