假设我获得了一个包含以下值的CSV:
0, 1.00, Hello
3, 2.13, World
.
.
.
是否有一个好的方法或库可以自动检测最佳类型以将给定列分类为?在这种情况下(Int,Float,String)。
对于更多上下文,我正在尝试扩展CSV解析库,以允许它报告传递的CSV上的数据直方图。这个想法是让很容易将某些验证任务添加到此框架中至于弄清楚CSV数据转储中的缺陷或不规范。
最初我想写一些用户可以提供指定类型的配置文件的东西,但是对于CSV列设置非常大的情况,或者只是为了易于使用,我想尝试自动检测类型而不是让用户必须写出来。
答案 0 :(得分:1)
答案可能是:
def parse(s:String): Any = Try(s.toInt) orElse(Try(s.toDouble)) getOrElse(s)
然后你可以使用模式匹配来随心所欲地做任何事情。
当然,您可以首先对字符串进行常规表达式测试,以查看您拥有的类型。但我相当肯定只是强制执行每种格式的解析,如上所述,会更快。
答案 1 :(得分:0)
考虑解析器组合器;推断类型通过案例类列表进行报告,
import scala.util.parsing.combinator._
trait CSVType
case class LiteralStr extends CSVType
case class Float extends CSVType
case class Integer extends CSVType
case class Bool extends CSVType
case class NA extends CSVType // Not Available
class CSV extends JavaTokenParsers {
def row: Parser[List[CSVType]] = repsep(value, ",")
def value: Parser[CSVType] =
floatingPointNumber ^^ { f => if (f.toDouble.toInt == f.toDouble) Integer()
else Float() } |
"NA" ^^ { na => NA() } |
("true" | "false") ^^ { b => Bool() } |
stringLiteral ^^ { s => LiteralStr() }
}
object ParseExpr extends CSV with App {
println("in: "+ args(0))
println(parseAll(row, args(0)))
}
因此
scala> val s = """1.23,2,true,NA,"hello" """
s: String = "1.23,2,true,NA,"hello" "
scala> ParseExpr.main(Array(s))
in: 1.23,2,true,NA,"hello"
[1.24] parsed: List(Float(), Integer(), Bool(), NA(), LiteralStr())
请注意,组合器包括类型的解析,例如数字,布尔值和字符串。此外,自定义类型由解析器定义,例如NA
。有关此处使用的定义,请参阅JavaTokenParsers trait。
每个案例类都可能包含额外的逻辑,以便以最方便的方式报告输入。