【问题标题】:Spark - How to count number of records by keySpark - 如何按键计算记录数
【发布时间】:2016-01-13 14:38:24
【问题描述】:

这可能是一个简单的问题,但基本上我有一个数据集来计算每个国家/地区的女性人数。最终,我想按国家/地区对每个计数进行分组,但我不确定该值使用什么,因为数据集中没有可用作 groupByKey 或 reduceByKey 中的值的计数列。我想过使用 reduceByKey() 但这需要一个键值对,我只想计算键并将计数器作为值。我该怎么做?

val lines = sc.textFile("/home/cloudera/desktop/file.txt")
val split_lines = lines.map(_.split(","))
val femaleOnly = split_lines.filter(x => x._10 == "Female")

这是我卡住的地方。该国在数据集中也是第 13 位。 输出应如下所示: (澳大利亚,201000) (美国,420000) ETC 任何帮助都会很棒。 谢谢

【问题讨论】:

  • 您是否有理由不想(暂时)添加值?您基本上可以像计算字数一样进行操作,并使所有 KV 对类似于 然后 reduceByKey 并对值求和。或者做key 然后reduceByKey 和sum 得到指定国家的女性人数。我不确定如何用 scala 做到这一点,但使用 python+spark 这很容易。

标签: hadoop apache-spark cloud


【解决方案1】:

你快到了!您只需要countByValue

val countOfFemalesByCountry = femaleOnly.map(_(13)).countByValue()
// Prints (Australia, 230), (America, 23242), etc.

(在您的示例中,我假设您的意思是 x(10) 而不是 x._10)

大家一起:

sc.textFile("/home/cloudera/desktop/file.txt")
    .map(_.split(","))
    .filter(x => x(10) == "Female")
    .map(_(13))
    .countByValue()

【讨论】:

  • 这是一个很好的答案。如何计算哈希图的哈希图。那就是我想对每种性别进行分组。像 sc.textFile("/home/cloudera/desktop/file.txt") .map(_.split(",")) .map(_(10)) .map(_(13)) .countByValue( )
  • 你不应该默认使用 countByValue,因为这会强制整个地图到主节点上(它返回一个非 RDD)。 apachesparkbook.blogspot.com/2015/11/countbyvalue-example.html 相反,您应该 femaleOnly.map((_(13), 1)).reduceByKey(_+_),它将所有计算和数据保存在工作节点上。
【解决方案2】:

您是否考虑过使用 Dataframes API 操作您的 RDD?

您似乎正在加载一个 CSV 文件,您可以使用 spark-csv 执行此操作。

那么这很简单(如果您的 CSV 标题带有明显的列名):

import com.databricks.spark.csv._

val countryGender = sqlContext.csvFile("/home/cloudera/desktop/file.txt") // already splits by field
  .filter($"gender" === "Female")
  .groupBy("country").count().show()

如果您想更深入地了解这种操作,以下是指南: https://spark.apache.org/docs/latest/sql-programming-guide.html

【讨论】:

    【解决方案3】:

    您可以轻松地创建一个,它不必在文件/数据库中。例如:

    val countryGender = sc.textFile("/home/cloudera/desktop/file.txt")
                    .map(_.split(","))
                    .filter(x => x._10 == "Female")
                    .map(x => (x._13, x._10))    // <<<< here you generate a new key
                    .groupByKey();
    

    【讨论】:

    • 你能不能用一个reduce函数来按国家统计记录?
    • 这将返回 。您可以再次映射类似 - val countryGenderCount = countryGender.map(lambda row : (row[0], len(row[1].data)))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-03
    • 1970-01-01
    相关资源
    最近更新 更多