Eclipse Scala-在多个字段上使用DF过滤器

Eclipse Scala-在多个字段上使用DF过滤器,eclipse,scala,dataframe,filter,Eclipse,Scala,Dataframe,Filter,我已经在stackoverflow中搜索了好几天了,我只是没有找到以下问题的答案。我对scala编码非常陌生,所以这可能是一个非常基本的问题。任何帮助都将不胜感激 我遇到的问题(出错)是最后一位代码。 我试图从一个数据帧中获取一个过滤记录子集,其中所有过滤记录都缺少来自一个或多个指定字段的数据 我正在Eclipse中使用Scala IDE Build 4.7.0。 我使用的pom.xml文件有spark-core_2.11版本2.0.0 谢谢。 杰西 spark.read.*函数将数据直接读取到

我已经在stackoverflow中搜索了好几天了,我只是没有找到以下问题的答案。我对scala编码非常陌生,所以这可能是一个非常基本的问题。任何帮助都将不胜感激

我遇到的问题(出错)是最后一位代码。
我试图从一个数据帧中获取一个过滤记录子集,其中所有过滤记录都缺少来自一个或多个指定字段的数据

我正在Eclipse中使用Scala IDE Build 4.7.0。
我使用的pom.xml文件有spark-core_2.11版本2.0.0

谢谢。
杰西


spark.read.*
函数将数据直接读取到Dataset/Dataframe API中,从而(在某种程度上)避免了对模式定义的需要,并且完全可以使用RDD API

val source_path = args(0)
val source_file = args(1)

val dfData = spark.read.textFile(source_path + "/" + source_file)
  .flatMap(l => {
    val a = l.split('\u001e'.toString, -1).map(_.trim())
    val f1 = a(0).toLong
    val f2 = a(1).toLong
    val Array(f3, f4, fa1, fa2, fa3, fa4, f5, f6, f7, f8) = a.slice(2,12)

    if (fa1 == "" ||
        fa2 == "" ||
        fa3 == "" ||
        fa4 == "") {
      Some(f1, f2, f3, f4, fa1, fa2, fa3, fa4, f5, f6, f7, f8)
    } else {
      None
    }
  }).toDF("FIELD_1", "FIELD_2", "FIELD_3", "FIELD_4",
          "FIELD_ADD_1", "FIELD_ADD_2", "FIELD_ADD_3", "FIELD_ADD_4",
          "FIELD_5", "FIELD_6", "FIELD_7", "FIELD_8")
我想这会得到你想要的。我相信有比我更好的人可以用更简洁的代码对此进行优化


请注意,数组的索引为零,如果有意选择特定字段,则必须调整这些字段。我也不确定
'\u001e'
(十六进制值30)是否是分割字符串所需的适当值。

为了更好的可见性,我要添加
apache spark
标记。在
val vRow…
行中,您正在执行
x.split(“,-1)
。那里的空字符串是故意的吗?这会分割成一个字符数组。还有,spark的哪个版本?如果
>=1.6
有更好的方法直接导入数据集。@TravisHegner,实际上在这些引号之间有一个未打印的字符,作为文件中的列分隔符存在。我想试着用下面的一行,这样会更清楚一点,但我还没有弄清楚如何正确地写它。val vSrcRow=vSrcFile.map(x=>x.split((char)30,-1)).map(x=>Row(另外,根据我与.scala代码文件一起使用的pom.xml文件,我有spark-core_2.11,版本2.0.0。如果您愿意共享,我将非常高兴看到一种更好的将文本文件读取到数据集中的方法。这看起来非常好。我将尝试将其合并到我的其余代码中,并让您知道它是如何实现的。)行得通。我需要只定义长的字段吗?很抱歉,我忘了指定字符的基数。我正在寻找十六进制1E或ASCII 30。因此,这看起来也应该行得通。非常感谢您的帮助!!没问题。
.split()
返回一个
数组[String]
因此,转换字符串字段是不必要的。非常感谢您提供的信息。我已经对其中的大部分内容进行了调整,以适应我正在尝试执行的操作。但是,我尝试使用的文件相当大(它有268列)。因此,当我将所有这些列都放在Some()方法中时,我得到以下错误:“应用了太多的方法参数:(x:A)object Some中的某些[A]。由于我不熟悉Some()方法,因此我不确定如何解决此问题。该方法的参数限制是什么?
Some()
方法实际上生成了一个
选项
,该选项基本上是长度为1的
可伸缩
。当执行
.flatMap()
时,该选项会变平。因此参数实际上表示为
一些[TupleX]
,但是
TupleX
的长度限制为22项(请阅读:
Tuple2
-
Tuple22
)。不幸的是,此解决方案对于如此多的列根本不起作用。将其余列保留为
String
s可以吗?如果可以,您可以发出
一些[(Long,Long,Array[String])
,它实际上是一个更干净的解决方案。如果不是,您有哪些列类型?
val source_path = args(0)
val source_file = args(1)

val dfData = spark.read.textFile(source_path + "/" + source_file)
  .flatMap(l => {
    val a = l.split('\u001e'.toString, -1).map(_.trim())
    val f1 = a(0).toLong
    val f2 = a(1).toLong
    val Array(f3, f4, fa1, fa2, fa3, fa4, f5, f6, f7, f8) = a.slice(2,12)

    if (fa1 == "" ||
        fa2 == "" ||
        fa3 == "" ||
        fa4 == "") {
      Some(f1, f2, f3, f4, fa1, fa2, fa3, fa4, f5, f6, f7, f8)
    } else {
      None
    }
  }).toDF("FIELD_1", "FIELD_2", "FIELD_3", "FIELD_4",
          "FIELD_ADD_1", "FIELD_ADD_2", "FIELD_ADD_3", "FIELD_ADD_4",
          "FIELD_5", "FIELD_6", "FIELD_7", "FIELD_8")