Scala 如何将上一行的键复制到键值对RDD中下一行的键字段

Scala 如何将上一行的键复制到键值对RDD中下一行的键字段,scala,apache-spark,rdd,Scala,Apache Spark,Rdd,样本数据集: $, Claw "OnCreativity" (2012) [Himself] $, Homo Nykytaiteen museo (1986) [Himself] <25> Suuri illusioni (1985) [Guests] <22> $, Steve E.R. Sluts (2003) (V) <12> $hort, Too 2012

样本数据集:

$, Claw         "OnCreativity" (2012)  [Himself]

$, Homo         Nykytaiteen museo (1986)  [Himself]  <25>
            Suuri illusioni (1985)  [Guests]  <22>

$, Steve        E.R. Sluts (2003) (V)  <12>

$hort, Too      2012 AVN Awards Show (2012) (TV)  [Himself - Musical Guest]
            2012 AVN Red Carpet Show (2012) (TV)  [Himself]
            5th Annual VH1 Hip Hop Honors (2008) (TV)  [Himself]
            American Pimp (1999)  [Too $hort]
控制台上的键值RDD输出:

Array(($, Claw,"OnCreativity" (2012)  [Himself]), ($, Homo,Nykytaiteen museo (1986)  [Himself]  <25>), ("",Suuri illusioni (1985)  [Guests]  <22>), ($, Steve,E.R. Sluts (2003) (V)  <12>).......
Array($,Claw,“OnCreativity”(2012)[他自己],($,Homo,Nykytaiten museo(1986)[他自己],('',Suuri illusioni(1985)[来宾],($,Steve,E.R.Sluts(2003)(V))。。。。。。。
但是,由于dataset的性质,很多行都将“”作为键,即为空(请参见上面的RDD输出),因此,我希望有一个函数,可以将前一行的参与者复制到这一行(如果它为空)。
如何做到这一点。

对Spark和Scala来说是个新概念。但也许更简单的方法是更改对行的解析,并首先创建一对具有list类型值的RDD,例如

($,Homo,(Nykytaiten museo(1986)[他本人]、Suuri illusioni(1985)[来宾])

我不知道您的数据,但如果一行不是以“$”开头,您可能会将其附加到值列表中

然后,根据您想要执行的操作,也许您可以在上面描述的RDD对上使用flatMapValues(func)。这将应用一个函数,该函数对RDD对的每个值返回一个迭代器,并为返回的每个元素生成一个带有旧键的键值项

增加: 您的输入数据(“样本数据集”)采用什么格式?是文本文件还是.tsv? 您可能希望一次加载整个文件。也就是说,使用.wholeTextFiles()而不是.textFile()加载数据。这是因为您的记录存储在文件中的多行中

增加 我不打算下载该文件,但在我看来,您感兴趣的每条记录都以“$”开头。 Spark可以使用任何Hadoop输入格式,因此请检查这些格式,看看是否有一种适用于您的示例数据


如果没有,您可以编写自己的Hadoop InputFormat实现,将文件解析为按此字符分割的记录,而不是文本文件的默认值,即“\n”字符。

继续xyzzy给出的想法,在将文件作为字符串加载后尝试此方法如何:

val actorFileSplit = actorsFile.split("\n\n")
val actorData = sc.parallelize(actorsFileSplit)
val actorDataSplit = actorsData.map(x => x.split("\t+",2).toList).map(line => (line(0), line(1).split("\n\t+").toList))
为了解释我在做什么,我首先在每次找到换行符时将字符串拆分。连续地,我将其并行化为用于映射函数的sparkcontext。然后,我将每个条目拆分为两部分,由第一次出现的多个制表符(一个或多个)分隔。第一部分现在应该是演员,第二部分仍然应该是带有电影标题的字符串。第二部分可以再次在每一行拆分,后面是一些选项卡。这将创建一个包含每个演员所有标题的列表。最终结果如下所示:

actorDataSplit = [(String, [String])]

祝你好运

我也是Spark和Scala的新手,请你举一个代码/命令和“$”方面的例子好吗是参与者名称的一部分,它会发生变化,因此我不能在正常逻辑中使用它。所描述的逻辑是不可交换的。RDD元素在不同的机器上进行分区,如果空白键的前一个元素在不同的机器上会怎么样?另外,我认为RDD数据结构没有顺序。我认为拥有解析日志会更简单ic,它将您的文件解析为一对RDD,其中包含演员姓名的键,以及演员所参与的所有电影的列表。您希望在Spark RDD API中应用的任何逻辑,我认为您都可以在解析文件和创建基本RDD时应用。我确实希望有一个解析逻辑来解析文件转换为一对RDD,密钥为actors name,值为actor参与的所有电影的列表,但在解析数据集时(可从下面的链接下载),仅通过解析无法真正将电影列表提取为值&演员为键,因为我们必须将行拆分为字段以形成一对。此外,它是一个以制表符分隔的数据集,如果我们使用.wholeTextFiles(),然后我们将在RDD中只得到一行。我建议使用一个用户定义的函数来复制前一行中的键(如果它是空的)。链接下载数据集,建议在这个巨大的文本文件中使用像VIM这样的文本编辑器。
actorDataSplit = [(String, [String])]