scala - Spark - 更改数据集中属于长尾的记录的值
问题描述
我正在尝试解决机器学习问题中的数据清理步骤,我应该将长尾中的所有元素分组到一个名为“其他”的通用类别中。例如,我有一个这样的数据框:
val df = sc.parallelize(Seq(
(1, "ABC"),
(2, "ABC"),
(3, "123"),
(4, "FPK"),
(5, "FPK"),
(6, "ABC"),
(7, "ABC"),
(8, "980"),
(9, "abc"),
(10, "FPK")
)).toDF("n", "s")
我想保留类别"ABC"
,"FPK"
因为它们出现了好几次,但我不想有一个不同的类别:123,980,abc
因为它们只出现一次。所以我想要的是:
+---+------+
| n| s|
+---+------+
| 1| ABC|
| 2| ABC|
| 3|Others|
| 4| FPK|
| 5| FPK|
| 6| ABC|
| 7| ABC|
| 8|Others|
| 9|Others|
| 10| FPK|
+---+------+
为了实现这一点,我尝试的是:
val newDF = df.withColumn("s",when($"s".isin("123","980","abc"),"Others").otherwise('s)
这工作正常。
但我想以编程方式决定哪些类别属于长尾,在我的情况下,在 originall 数据框中只出现一次。所以我写了这个来创建一个数据框,其中包含那些只出现一次的类别:
val longTail = df.groupBy("s").agg(count("*").alias("cnt")).orderBy($"cnt".desc).filter($"cnt"<2)
+---+---+
| s|cnt|
+---+---+
|980| 1|
|abc| 1|
|123| 1|
+---+---+
现在我试图将这个 longTail 数据集中的“s”列的值转换为一个列表,以便用我之前硬编码的那个来交换它。所以我尝试了:
val ar = longTail.select("s").collect().map(_(0)).toList
ar: List[Any] = List(123, 980, abc)
但是当我尝试添加 ar
val newDF = df.withColumn("s",when($"s".isin(ar),"Others").otherwise('s))
我收到以下错误:
java.lang.RuntimeException:不支持的文字类型类 scala.collection.immutable.$colon$colon List(123, 980, abc)
我错过了什么?
解决方案
这是正确的语法:
scala> df.withColumn("s", when($"s".isin(ar : _*), "Others").otherwise('s)).show
+---+------+
| n| s|
+---+------+
| 1| ABC|
| 2| ABC|
| 3|Others|
| 4| FPK|
| 5| FPK|
| 6| ABC|
| 7| ABC|
| 8|Others|
| 9|Others|
| 10| FPK|
+---+------+
这称为重复参数。参考这里。
推荐阅读
- javascript - 如何确保我不会在 React 中遇到异常错误或任何类型的停止执行或使应用程序崩溃的错误
- mysql - 无法加载或组装“Renci.SshNet,版本=2016.1.0.0,文化=中性,publickeytoken=1cee9fbde3db106”
- swift - InputAccessoryView 和我的问题 (Swift)
- android-emulator - Android Studio Emulator 未显示“始终位于顶部”切换按钮。如何设置它始终在顶部?
- html - 当使用比例效应变大时,如何阻止我的文本变得模糊?
- sorting - 在 Neo4j 中,来自 apoc.path.spanningTree 的路径将根据什么进行排序(默认排序)?
- sql - sql server 中简单 UNION 的替代方案
- python - 如何在 DestroyAPI SUccess MEssage 中传递字典
- elasticsearch - 可以直接读取/解析弹性搜索索引文件吗?
- php - “2020 年 3 月 10 日至 20 日”我需要两个日期的这种日期格式