繁体   English   中英

如何使用Spark中的Scala从数据框中的单元格中提取表信息

[英]How to extract table information from a cell in dataframe using Scala in Spark

我需要提取与数据框行中的单元格制表符分隔的数据

我尝试使用Splitted方法,但无法正常工作

val df = spark.sql("select _time, _raw, host from logs")

    val extractedData = df.filter(
      $"host" === "ausflscgap01.us.dell.com" ||
      $"host" ==="ausflscgap02.us.dell.com" ||
      $"host" === "ausplscgap01.us.dell.com" ||
      $"host" === "ausplscgap02.us.dell.com")
    .withColumn("splitted", split($"_raw", "\t"))
      .select($"splitted".getItem(5)
        .alias("pctIdle"))
      .show()

该行中的实际数据:

CPU    pctUser    pctNice  pctSystem  pctIowait    pctIdle
all       9.55       0.00      36.18       1.51      52.76
0        10.00       0.00      37.00       4.00      49.00
1         9.00       0.00      34.00       0.00      57.00

我只需要提取“所有”行的pctIdle列的预期输出

pctIdle
52.76

如果我对您的理解正确,并且您在日志表的_raw文本字段中具有“ 该行中的实际数据 ”,那么您需要执行以下操作:

import org.apache.spark.sql.functions._

val extractPctIdle = udf{(raw: String) =>
raw
  .split("\n")
  .map(_.split("\t"))
  .find(_(0) == "all")
  .map(_(5))
  .getOrElse("unknown")
}

val extractedData = df.filter(
      $"host" === "ausflscgap01.us.dell.com" ||
        $"host" ==="ausflscgap02.us.dell.com" ||
        $"host" === "ausplscgap01.us.dell.com" ||
        $"host" === "ausplscgap02.us.dell.com")
      .withColumn("pctIdle", extractPctIdle($"_raw"))
      .show()

也就是说,您可以通过自定义udf解析_raw字段。 它是最简单的版本,但是最好在_raw字段格式错误的情况下进行一些错误处理。

该案例以这种方式建模:

case class R(host: String, _raw: String)

val df = Seq(
      R("ausflscgap02.us.dell.com", "CPU\tpctUser\tpctNice\tpctSystem\tpctIowait\tpctIdle\nall\t9.55\t0.00\t36.18\t1.51\t52.76\n0\t10.00\t0.00\t37.00\t4.00\t49.00\n1\t9.00\t0.00\t34.00\t0.00\t57.00"),
      R("ausplscgap01.us.dell.com", "CPU\tpctUser\tpctNice\tpctSystem\tpctIowait\tpctIdle\nall\t9.55\t0.00\t36.18\t1.51\t52.76\n0\t10.00\t0.00\t37.00\t4.00\t49.00\n1\t9.00\t0.00\t34.00\t0.00\t57.00")
    ).toDF()

编辑

如果您需要_raw内几列中的数据:

case class RawInfo(pctUser: String, pctIdle: String)

val extractRawInfo = udf{(raw: String) =>
      val all = raw
        .split("\n")
        .map(_.split("\t"))
        .find(_(0) == "all")

      def getValue(pos: Int) = all.map(_(pos)).getOrElse("unknown")

      RawInfo(
        pctUser = getValue(1),
        pctIdle = getValue(5))
    }

    df.filter($"host".isin("ausflscgap01.us.dell.com", "ausflscgap02.us.dell.com", "ausplscgap01.us.dell.com", "ausplscgap02.us.dell.com"))
      .withColumn("info", extractRawInfo($"_raw"))
      .select("host", "info.pctUser", "info.pctIdle")
      .show()

备注:可能只从udf返回Array [string]并在以后检索特定的列(例如$“ info”(0).as(“ pctUser”)),但是我更喜欢上面显示的类型化解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM