我在s3位置存储了csv,其中包含类似的数据
column1 | column2 |
--------+----------
| adsf | 2000.0 |
| fff | 232.34 |
我在Scala中有一个AWS Glue作业,它将这个文件读取到数据帧中
var srcDF= glueContext.getCatalogSource(database = '',
tableName = '',
redshiftTmpDir = "",
transformationContext = "").getDynamicFrame().toDF()
当我打印模式时,它会像这个一样推断自己
srcDF.printSchema()
|-- column1 : string |
|-- column2 : struct (double, string) |
数据帧看起来像
column1 | column2 |
--------+-------------
| adsf | [2000.0,] |
| fff | [232.34,] |
当我试图将数据帧保存到csv时,它会抱怨
org.apache.spark.sql.AnalysisException CSV data source does not support struct<double:double,string:string> data type.
如何将数据帧转换为只有Struct类型的列(如果存在(为十进制类型?像这样的输出
column1 | column2 |
--------+----------
| adsf | 2000.0 |
| fff | 232.34 |
编辑:
感谢您的回复。我已经尝试使用以下代码
df.select($"column2._1".alias("column2")).show()
但两个都出现了相同的错误
org.apache.spark.sql.AnalysisException No such struct field _1 in double, string;
编辑2:
这似乎是星星之火,柱子被压扁并改名为";双,字符串";
所以,这个解决方案对我有效
df.select($"column2.double").show()
您可以使用getItem
从结构中提取字段。代码可以是这样的:
import spark.implicits._
import org.apache.spark.sql.functions.{col, getItem}
val df = Seq(
("adsf", (2000.0,"")),
("fff", (232.34,""))
).toDF("A", "B")
df.show()
df.select(col("A"), col("B").getItem("_1").as("B")).show()
它将打印:
before select:
+----+----------+
| A| B|
+----+----------+
|adsf|[2000.0, ]|
| fff|[232.34, ]|
+----+----------+
after select:
+----+------+
| A| B|
+----+------+
|adsf|2000.0|
| fff|232.34|
+----+------+
您还可以使用点表示法column2._1
按名称获取结构字段:
val df = Seq(
("adsf", (2000.0,"")),
("fff", (232.34,""))
).toDF("column1", "column2")
df.show
+-------+----------+
|column1| column2|
+-------+----------+
| adsf|[2000.0, ]|
| fff|[232.34, ]|
+-------+----------+
val df2 = df.select($"column1", $"column2._1".alias("column2"))
df2.show
+-------+-------+
|column1|column2|
+-------+-------+
| adsf| 2000.0|
| fff| 232.34|
+-------+-------+
df2.coalesce(1).write.option("header", "true").csv("output")
并且您的csv文件将在output/
文件夹中:
column1,column2
adsf,2000.0
fff,232.34