Spark - 如何按键计算记录数

11

这可能是一个简单的问题,但基本上我有一个数据集,需要统计每个国家的女性数量。最终,我想按国家分组每个计数,但我不确定要使用什么值,因为数据集中没有可以用作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) 等等 任何帮助将非常感谢。 谢谢。


你不想(暂时)添加值的原因是什么?您可以像单词计数一样将所有KV对设为<female, 1>,然后通过reduceByKey和sum函数来计算总和。或者将键设置为<[female, australia],1>,然后根据国家/地区减少键并进行求和以获得指定国家/地区的女性人数。我不确定如何在Scala中实现此操作,但是使用Python+Spark非常容易。 - TravisJ
3个回答

17

你已经快成功了!你所需要的只是一个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() - user1579557
不应默认使用countByValue,因为它会将整个映射强制到主节点上(返回非RDD)。http://apachesparkbook.blogspot.com/2015/11/countbyvalue-example.html 相反,您应该使用femaleOnly.map((_(13), 1)).reduceByKey(_+_),这将保持所有计算和数据在工作节点上。 - Multihunter

5

您是否考虑使用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


0

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

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函数完成这个任务,按国家统计记录数量吗? - Jeff Parker
1
这将返回<键,可迭代>。您可以再次映射类似以下的内容 - val countryGenderCount = countryGender.map(lambda row : (row[0], len(row[1].data))) - Saksham

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接