示例数据集:
$, 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:
To split data: val actorTuple = actor.map(l => l.split("\t"))
To make KV pair: val actorKV = actorTuple.map(l => (l(0), l(l.length-1))).filter{case(x,y) => y != "" }
控制台上的键值RDD输出:
Array(($, Claw,"OnCreativity" (2012) [Himself]), ($, Homo,Nykytaiteen museo (1986) [Himself] <25>), ("",Suuri illusioni (1985) [Guests] <22>), ($, Steve,E.R. Sluts (2003) (V) <12>).......
但是,很多行都将这个“”作为键,即空白(参见上面的RDD输出),因为数据集的性质,所以,我希望有一个函数将前一行的actor复制到此如果它是空的那一行。 如何做到这一点。
答案 0 :(得分:1)
Spark和Scala的新手。但也许改变你的行解析会更简单,并且首先创建一个具有list类型值的RDD对,例如。
($,Homo,(Nykytaiteen museo(1986)[Himself]&lt; 25&gt;,Suuri illusioni(1985)[嘉宾]&lt; 22&gt;))
我不知道您的数据,但也许如果一行不以&#34; $&#34;您附加到值列表。
然后根据你想要做的事情,也许你可以在上面描述的对RDD上使用flatMapValues(func)。这将应用一个函数,该函数将迭代器返回到RDD对的每个值,并且对于返回的每个元素,使用旧键生成键值条目。
增加: 您的输入数据是什么格式(&#34;示例数据集&#34;)?它是文本文件还是.tsv? 您可能想要一次加载整个文件。也就是说,使用.wholeTextFiles()而不是.textFile()来加载数据。这是因为您的记录存储在文件中的多行中。
ADDED 我不打算下载该文件,但在我看来,您感兴趣的每条记录都以&#34; $&#34;开头。 Spark可以使用任何Hadoop输入格式,因此请检查它们是否有适用于您的示例数据的格式。
如果没有,您可以编写自己的Hadoop InputFormat实现,将文件解析为拆分在此字符上的记录,而不是TextFiles的默认值,即&#39; \ n&#39;字符。
答案 1 :(得分:1)
继续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。然后我将每个条目分成两个部分,这两部分由多个标签(一个或多个)的第一次出现分隔。第一部分现在应该是演员,第二部分应该仍然是电影片名的字符串。第二部分可以再次在每个新行分开,然后是多个标签。这应该创建一个列表,其中包含每个actor的所有标题。最终结果如下:
actorDataSplit = [(String, [String])]
祝你好运