Spark数据框操作

时间:2020-09-24 11:41:14

标签: dataframe apache-spark apache-spark-sql

我正在尝试对数据框执行非常具体的操作,但是我找不到一种很好的方法。

我有一个看起来像这样的数据框:

+------------------+----------------+--------+
|CIVILITY_PREDICTED|COUNTRY_CODE_PRE|    name|
+------------------+----------------+--------+
|                 M|              CA|A HANNAN|
|                 M|              CA|   A JAY|
|                 M|              GB|   A JAY|
|                 M|              CA| A K I L|
|                 F|              CA|   A LAH|
|                 ?|              CN|  A LIAN|
|                 ?|              CN|   A MEI|
|                 ?|              CN|   A MIN|
|                 F|              CA|   A RIN|
|                 M|              CA|   A S M|
|                 ?|              CN|  A YING|
|                 F|              CA|AA ISHAH|
|                 M|              CA|   AABAN|
|                 M|              GB|   AABAN|
|                 M|              US|   AABAN|
|                 M|              GB|   AABAS|
|                 F|              CA|  AABEER|
|                 M|              CA|   AABEL|
|                 F|              US|   AABHA|
|                 F|              GB|   AABIA|
+------------------+----------------+--------+

正如您在CIVILITY_PREDICTED中看到的那样,我有一些“?” 。 每个国家/地区的每个“名称”都有一行,有时CIVILITY_PREDICTED是“?”一个国家/地区,但另一个国家/地区名称相同。

所以基本上我想要每个“?”添加基于其他国家/地区的最常用的CIVILITY_PREDICTED。

我试图通过这样做来做到这一点(e是数据框,to_predict是另一个仅具有我要获取的名称的对象):

e.filter($"CIVILITY_PREDICTED" === "?" && $"name".isNotNull)
.select("COUNTRY_CODE_PRE","CIVILITY_PREDICTED","name").
collect().map(a => {
    to_predict
    .filter($"name" === a.get(3))
    .filter( $"CIVILITY_PREDICTED" !== "?")
    .groupBy("CIVILITY_PREDICTED")
    .count()
    .agg(org.apache.spark.sql.functions.max("CIVILITY_PREDICTED")).show()

有了这个,我得到每个名字中出现次数最多的CIVLITY_PREDICTED,但是我想它不是很理想,我不知道该如何替换相应的“?”在这个数据框中。

有人知道吗?非常感谢

1 个答案:

答案 0 :(得分:0)

窗口功能是这里的关键。以下解决方案使用first_value根据行数选择第一个性别值。

spark.sql("""select distinct name, first_value(CIVILITY_PREDICTED) over (partition by name order by count(*) desc) civility
             from civ
             group by name, CIVILITY_PREDICTED
             """).show

根据如下所示重新创建的数据,返回:

+-----+--------+
| name|civility|
+-----+--------+
|AABAN|       M|
+-----+--------+

要查看原始值以及最常见的值:

spark.sql("""select name, CIVILITY_PREDICTED, 
             first(CIVILITY_PREDICTED) 
              over (partition by name order by count(*) desc) civility
             from civ 
             group by 1,2 
             order by 1,2
             """).show

返回

+-----+------------------+--------+
| name|CIVILITY_PREDICTED|civility|
+-----+------------------+--------+
|AABAN|                 ?|       M|
|AABAN|                 M|       M|
+-----+------------------+--------+

对于您要解决的问题,我仅重新创建了一个名称。 AABAN是吗?代表一行,“ M”代表另外两行。

val civ = """+------------------+----------------+--------+
|CIVILITY_PREDICTED|COUNTRY_CODE_PRE|    name|
+------------------+----------------+--------+
|                 ?|              CA|   AABAN|
|                 M|              GB|   AABAN|
|                 M|              US|   AABAN|""".stripMargin.replaceAll("\\+", "").replaceAll("\\-", "").split("\n").filter(_.size>10)

val df = spark.read
  .option("ignoreTrailingWhiteSpace", "true")
  .option("ignoreLeadingWhiteSpace", "true")
  .option("delimiter", "|")
  .option("header", "true")
  .csv(spark.sparkContext.parallelize(civ).toDS)
  .drop("_c3")

df.createOrReplaceTempView("civ")

df.orderBy("name").show(99)

+------------------+----------------+-----+
|CIVILITY_PREDICTED|COUNTRY_CODE_PRE| name|
+------------------+----------------+-----+
|                 ?|              CA|AABAN|
|                 M|              GB|AABAN|
|                 M|              US|AABAN|
+------------------+----------------+-----+

相关问题