当前位置: 首页 > 知识库问答 >
问题:

火花SQL:选择与算术列值和类型转换?

呼延弘方
2023-03-14

我将Spark SQL用于数据帧。有没有一种方法可以像在SQL中一样,使用一些算术来执行select语句?

例如,我有以下表格:

var data = Array((1, "foo", 30, 5), (2, "bar", 35, 3), (3, "foo", 25, 4))
var dataDf = sc.parallelize(data).toDF("id", "name", "value", "years")

dataDf.printSchema
// root
//  |-- id: integer (nullable = false)
//  |-- name: string (nullable = true)
//  |-- value: integer (nullable = false)
//  |-- years: integer (nullable = false)

dataDf.show()
// +---+----+-----+-----+
// | id|name|value|years|
// +---+----+-----+-----+
// |  1| foo|   30|    5|
// |  2| bar|   35|    3|
// |  3| foo|   25|    4|
//+---+----+-----+-----+

现在,我想用SELECT语句创建一个新列,并对现有列执行一些算术运算。例如,我想计算比率值/年。我需要先把价值(或年数)转换成双倍。我试过这句话,但无法解析:

dataDf.
    select(dataDf("name"), (dataDf("value").toDouble/dataDf("years")).as("ratio")).
    show()

<console>:35: error: value toDouble is not a member of org.apache.spark.sql.Column
              select(dataDf("name"), (dataDf("value").toDouble/dataDf("years")).as("ratio")).

我在“如何在Spark SQL的DataFrame中更改列类型?”中看到了类似的问题,但这不是我想要的。

共有2个答案

东门茂实
2023-03-14

如果不需要使用选择方法,您可以只使用列方法。

val resDF = dataDf.withColumn("result", col("value").cast("double") / col("years"))
resDF.show

//+---+----+-----+-----+------------------+
//| id|name|value|years|            result|
//+---+----+-----+-----+------------------+
//|  1| foo|   30|    5|               6.0|
//|  2| bar|   35|    3|11.666666666666666|
//|  3| foo|   25|    4|              6.25|
//+---+----+-----+-----+------------------+

如果要求使用选择,一个选项可以是:

val exprs = dataDf.columns.map(col(_)) ++ List((col("value").cast("double") / col("years")).as("result"))
dataDf.select(exprs: _*).show

//+---+----+-----+-----+------------------+
//| id|name|value|years|            result|
//+---+----+-----+-----+------------------+
//|  1| foo|   30|    5|               6.0|
//|  2| bar|   35|    3|11.666666666666666|
//|  3| foo|   25|    4|              6.25|
//+---+----+-----+-----+------------------+
柯瀚海
2023-03-14

更改类型的正确方法是使用cast方法。它可以采用描述字符串:

dataDf("value").cast("double") / dataDf("years")

或一个DataType

import org.apache.spark.sql.types.DoubleType

dataDf("value").cast(DoubleType) / dataDf("years")
 类似资料:
  • 数据-我使用XML中的许多附加列获取此类数据,并使用com。databricks spark-xml\u 2.11库,用于将xml数据转换为数据帧。 要求-必须从数组(struct)类型或列custom\u属性转换数据。示例中的custom\u属性,如示例输出所示。My struct有三个字段,分别命名为“\u VALUE”、“属性\u id”、“值”。我需要将属性id转换为列名称,数据为-检查“

  • 我使用rdd读取csv文件,只从dataframe中获取一列,并使用scala toArray将其转换为数组。 之后,我在sql中使用这个数组来检查这个数组中是否有一个字段值。 我使用Postgresql和jooq 3.11,但无论我怎么努力,我不能呈现sql,因为它需要。 下面的代码是。但是,它不会生成sql。我在用和,以及()中的相同问题的版本:

  • 问题内容: 如果我只需要2/3列,而是查询而不是在select查询中提供这些列,那么关于更多/更少I / O或内存的性能是否会有所下降? 如果我确实选择了*,则可能会出现网络开销。 但是在选择操作中,数据库引擎是否总是从磁盘中提取原子元组,还是仅提取在选择操作中请求的那些列? 如果它总是拉一个元组,则I / O开销是相同的。 同时,如果它拉出一个元组,从元组中剥离请求的列可能会占用内存。 因此,在

  • 问题内容: 这是桌子:- 而下面是一个 虚构的 sql 预期的结果是:- (一种) (B) (C) 最喜欢’A’的情况! 我知道这种情况与组合有关。 在现实世界中-客户从商店获得商品,并且由于他与商店之间达成协议,他每个星期五都付款。例如,付款金额不是项目的确切总和:他得到5册50钪(= 250钪)的书,而星期五他带来了150册。所以前3本书非常匹配-3 * 50 = 150.我需要找到那三本书的

  • 问题内容: 假设我有这个(MySQL)数据库,按增加的时间戳排序: 如何从该系统的上一行中选择StatusA更改的行?StatusB无关紧要(我在此问题中展示它只是为了说明每个系统可能有许多连续的行,其中StatusA不变)。在上面的示例中,查询应返回2011-01-03行(对于SystemA,StatusA在2011-01-01和2011-01-03之间更改),2011-01-06、2011-0

  • 问题内容: 我有一个带有列名称的数据表: 其中“列”包含数字值,“期间”列是具有1到48的标识列,因此有48行。 我想将此表按摩成一种格式,在该格式中,我具有“名称”列和“值”列以及“期间”列。 我想创建原始表的视图来执行此操作吗?如何选择列名称,并将其以及该列中的正确值放入NameOfVehicle和Value列中? 问题答案: 如果您有固定的列,则始终可以执行以下操作: 如果列是动态的或未知的