groupBykey in spark

时间:2015-08-13 01:49:48

标签: scala apache-spark

这里引发了新的兴趣,我正试图在spark中读取一个以管道分隔的文件。我的文件看起来像这样:

user1|acct01|A|Fairfax|VA
user1|acct02|B|Gettysburg|PA
user1|acct03|C|York|PA
user2|acct21|A|Reston|VA
user2|acct42|C|Fairfax|VA
user3|acct66|A|Reston|VA

我在scala中执行以下操作:

scala> case class Accounts (usr: String, acct: String, prodCd: String, city: String, state: String)
defined class Accounts

scala> val accts = sc.textFile("accts.csv").map(_.split("|")).map(
     | a => (a(0), Accounts(a(0), a(1), a(2), a(3), a(4)))
     | )

然后我尝试按键对键值对进行分组,这不确定我是否正确行事......这是我怎么做的?

scala> accts.groupByKey(2)
res0: org.apache.spark.rdd.RDD[(String, Iterable[Accounts])] = ShuffledRDD[4] at groupByKey at <console>:26

我认为(2)是给我前两个结果,但我似乎没有得到任何回到控制台......

如果我运行一个独特的...我也得到了这个......

scala> accts.distinct(1).collect(1)
<console>:26: error: type mismatch;
 found   : Int(1)
 required: PartialFunction[(String, Accounts),?]
              accts.distinct(1).collect(1)

编辑: 本质上我正在尝试使用键值对嵌套映射。例如,user1会像这样说:

user1 | {'acct01': {prdCd: 'A', city: 'Fairfax', state: 'VA'}, 'acct02': {prdCd: 'B', city: 'Gettysburg', state: 'PA'}, 'acct03': {prdCd: 'C', city: 'York', state: 'PA'}}

试着逐步学习这个,以为我会把它分解成块来理解......

2 个答案:

答案 0 :(得分:0)

如果您已经完成了定义架构的过程,那么如果您将数据放入DataFrame,我认为您可能会有更好的运气。首先,您需要修改拆分注释以使用单引号。 (见this question)。此外,您可以在开头摆脱a(0)。然后,转换为DataFrame是微不足道的。 (请注意,DataFrames在spark 1.3 +上可用。)

val accts = sc.textFile("/tmp/accts.csv").map(_.split('|')).map(a => Accounts(a(0), a(1), a(2), a(3), a(4)))
val df = accts.toDF()

现在df.show产生:

+-----+------+------+----------+-----+
|  usr|  acct|prodCd|      city|state|
+-----+------+------+----------+-----+
|user1|acct01|     A|   Fairfax|   VA|
|user1|acct02|     B|Gettysburg|   PA|
|user1|acct03|     C|      York|   PA|
|user2|acct21|     A|    Reston|   VA|
|user2|acct42|     C|   Fairfax|   VA|
|user3|acct66|     A|    Reston|   VA|
+-----+------+------+----------+-----+

您应该更容易处理数据。例如,要获取唯一用户的列表:

df.select("usr").distinct.collect()

产生

res42: Array[org.apache.spark.sql.Row] = Array([user1], [user2], [user3])

有关详细信息,请查看docs

答案 1 :(得分:0)

3个可能有助于您理解问题的观察结果:

1) groupByKey(2)不返回前2个结果,参数2用作结果RDD的分区数。请参阅docs

2)collect不接受Int参数。请参阅docs

3)split有两种类型的参数:CharString。字符串版本使用正则表达式,因此"|"如果打算作为文字,则需要转义。