Spark 1.5。
私はデータベースからintegers
としてロードしている30のIDの列を持っています:
_val numsRDD = sqlContext
.table(constants.SOURCE_DB + "." + IDS)
.select("id")
.distinct
.map(row=>row.getInt(0))
_
これはnumsRDD
の出力です:
_numsRDD.collect.foreach(println(_))
643761
30673603
30736590
30773400
30832624
31104189
31598495
31723487
32776244
32801792
32879386
32981901
33469224
34213505
34709608
37136455
37260344
37471301
37573190
37578690
37582274
37600896
37608984
37616677
37618105
37644500
37647770
37648497
37720353
37741608
_
すぐに、すべてのの組み合わせを生成し、それらのids
について、それぞれの組み合わせを< tripletID: String, triplet: Array(Int)>
の形式のタプルとして保存し、それをdataframe、私は次のようにします:
_// |combinationsDF| = 4060 combinations
val combinationsDF = sc
.parallelize(numsRDD
.collect
.combinations(3)
.toArray
.map(row => row.sorted)
.map(row => (
List(row(0), row(1), row(2)).mkString(","),
List(row(0), row(1), row(2)).toArray)))
.toDF("tripletID","triplet")
_
私がそれをするやいなや、combinationsDF
の内容の一部を印刷して、すべてが本来あるべき方法であることを確認します。だから私はこれを試してください:
_combinationsDF.show
_
返されるもの:
_+--------------------+--------------------+
| tripletID| triplet|
+--------------------+--------------------+
|,37136455,3758227...|[32776244, 371364...|
|,37136455,3761667...|[32776244, 371364...|
|,32776244,3713645...|[31723487, 327762...|
|,37136455,3757869...|[32776244, 371364...|
|,32776244,3713645...|[31598495, 327762...|
|,37136455,3760089...|[32776244, 371364...|
|,37136455,3764849...|[32776244, 371364...|
|,37136455,3764450...|[32776244, 371364...|
|,37136455,3747130...|[32776244, 371364...|
|,32981901,3713645...|[32776244, 329819...|
|,37136455,3761810...|[32776244, 371364...|
|,34213505,3713645...|[32776244, 342135...|
|,37136455,3726034...|[32776244, 371364...|
|,37136455,3772035...|[32776244, 371364...|
|2776244,37136455...|[643761, 32776244...|
|,37136455,3764777...|[32776244, 371364...|
|,37136455,3760898...|[32776244, 371364...|
|,32879386,3713645...|[32776244, 328793...|
|,32776244,3713645...|[31104189, 327762...|
|,32776244,3713645...|[30736590, 327762...|
+--------------------+--------------------+
only showing top 20 rows
_
明らかなように、すべてのtripletID
の最初の要素が欠落しています。したがって、次のようにtake(20)
を100%確実に使用します。
_combinationsDF.take(20).foreach(println(_))
_
以下のように、より詳細な表現を返します。
_[,37136455,37582274,WrappedArray(32776244, 37136455, 37582274)]
[,37136455,37616677,WrappedArray(32776244, 37136455, 37616677)]
[,32776244,37136455,WrappedArray(31723487, 32776244, 37136455)]
[,37136455,37578690,WrappedArray(32776244, 37136455, 37578690)]
[,32776244,37136455,WrappedArray(31598495, 32776244, 37136455)]
[,37136455,37600896,WrappedArray(32776244, 37136455, 37600896)]
[,37136455,37648497,WrappedArray(32776244, 37136455, 37648497)]
[,37136455,37644500,WrappedArray(32776244, 37136455, 37644500)]
[,37136455,37471301,WrappedArray(32776244, 37136455, 37471301)]
[,32981901,37136455,WrappedArray(32776244, 32981901, 37136455)]
[,37136455,37618105,WrappedArray(32776244, 37136455, 37618105)]
[,34213505,37136455,WrappedArray(32776244, 34213505, 37136455)]
[,37136455,37260344,WrappedArray(32776244, 37136455, 37260344)]
[,37136455,37720353,WrappedArray(32776244, 37136455, 37720353)]
[2776244,37136455,WrappedArray(643761, 32776244, 37136455)]
[,37136455,37647770,WrappedArray(32776244, 37136455, 37647770)]
[,37136455,37608984,WrappedArray(32776244, 37136455, 37608984)]
[,32879386,37136455,WrappedArray(32776244, 32879386, 37136455)]
[,32776244,37136455,WrappedArray(31104189, 32776244, 37136455)]
[,32776244,37136455,WrappedArray(30736590, 32776244, 37136455)]
_
したがって、tripletID
からの最初のIDは、何らかの理由で非推奨になっていると確信しています。それでも、take(20)
の代わりにcollect
を使用しようとすると:
_combinationsDF.collect.foreach(println(_))
_
すべてが再び元気になります(!!!):
_[32776244,37136455,37582274,WrappedArray(32776244, 37136455, 37582274)]
[32776244,37136455,37616677,WrappedArray(32776244, 37136455, 37616677)]
[31723487,32776244,37136455,WrappedArray(31723487, 32776244, 37136455)]
[32776244,37136455,37578690,WrappedArray(32776244, 37136455, 37578690)]
[31598495,32776244,37136455,WrappedArray(31598495, 32776244, 37136455)]
[32776244,37136455,37600896,WrappedArray(32776244, 37136455, 37600896)]
[32776244,37136455,37648497,WrappedArray(32776244, 37136455, 37648497)]
[32776244,37136455,37644500,WrappedArray(32776244, 37136455, 37644500)]
[32776244,37136455,37471301,WrappedArray(32776244, 37136455, 37471301)]
[32776244,32981901,37136455,WrappedArray(32776244, 32981901, 37136455)]
[32776244,37136455,37618105,WrappedArray(32776244, 37136455, 37618105)]
[32776244,34213505,37136455,WrappedArray(32776244, 34213505, 37136455)]
[32776244,37136455,37260344,WrappedArray(32776244, 37136455, 37260344)]
[32776244,37136455,37720353,WrappedArray(32776244, 37136455, 37720353)]
[643761,32776244,37136455,WrappedArray(643761, 32776244, 37136455)]
[32776244,37136455,37647770,WrappedArray(32776244, 37136455, 37647770)]
[32776244,37136455,37608984,WrappedArray(32776244, 37136455, 37608984)]
[32776244,32879386,37136455,WrappedArray(32776244, 32879386, 37136455)]
[31104189,32776244,37136455,WrappedArray(31104189, 32776244, 37136455)]
[30736590,32776244,37136455,WrappedArray(30736590, 32776244, 37136455)]
...
_
1. RDDへの組み合わせの配列をparallelize
する直前のステップを徹底的に照会しましたが、すべて問題ありません。 2. parallelize
が適用された直後に出力を印刷し、再びすべてが正常である。 3.問題は、numsRDDからDFへの変換に関連しているように見えますが、最善を尽くしても対処できません。 4.また、同じコードスニペットを使用してモックデータの問題を再現することもできませんでした。
したがって、まず:この問題の原因は何ですか?および2番目:どのように修正しますか?
元のnumsRDD
を確認します。空の文字列またはnull値がある可能性があります。これは私のために働く:
scala> val numsRDD = sc.parallelize(0 to 30)
numsRDD: org.Apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[0] at parallelize at <console>:27
scala> :pa
// Entering paste mode (ctrl-D to finish)
val combinationsDF = sc
.parallelize(numsRDD
.collect
.combinations(3)
.toArray
.map(row => row.sorted)
.map(row => (
List(row(0), row(1), row(2)).mkString(","),
List(row(0), row(1), row(2)).toArray)))
.toDF("tripletID","triplet")
// Exiting paste mode, now interpreting.
combinationsDF: org.Apache.spark.sql.DataFrame = [tripletID: string, triplet: array<int>]
scala> combinationsDF.show
+---------+----------+
|tripletID| triplet|
+---------+----------+
| 0,1,2| [0, 1, 2]|
| 0,1,3| [0, 1, 3]|
| 0,1,4| [0, 1, 4]|
| 0,1,5| [0, 1, 5]|
| 0,1,6| [0, 1, 6]|
| 0,1,7| [0, 1, 7]|
| 0,1,8| [0, 1, 8]|
| 0,1,9| [0, 1, 9]|
| 0,1,10|[0, 1, 10]|
| 0,1,11|[0, 1, 11]|
| 0,1,12|[0, 1, 12]|
| 0,1,13|[0, 1, 13]|
| 0,1,14|[0, 1, 14]|
| 0,1,15|[0, 1, 15]|
| 0,1,16|[0, 1, 16]|
| 0,1,17|[0, 1, 17]|
| 0,1,18|[0, 1, 18]|
| 0,1,19|[0, 1, 19]|
| 0,1,20|[0, 1, 20]|
| 0,1,21|[0, 1, 21]|
+---------+----------+
only showing top 20 rows
私が考えることができる他の唯一のものは、mkString
が期待どおりに機能しないことです。この文字列補間を試してください(List
を再作成する必要もありません):
val combinationsDF = sc
.parallelize(numsRDD
.collect
.combinations(3)
.toArray
.map(row => row.sorted)
.map{case List(a,b,c) => (
s"$a,$b,$c",
Array(a,b,c))}
.toDF("tripletID","triplet")
scala> combinationsDF.show
+---------+----------+
|tripletID| triplet|
+---------+----------+
| 0,1,2| [0, 1, 2]|
| 0,1,3| [0, 1, 3]|
| 0,1,4| [0, 1, 4]|
| 0,1,5| [0, 1, 5]|
| 0,1,6| [0, 1, 6]|
| 0,1,7| [0, 1, 7]|
| 0,1,8| [0, 1, 8]|
| 0,1,9| [0, 1, 9]|
| 0,1,10|[0, 1, 10]|
| 0,1,11|[0, 1, 11]|
| 0,1,12|[0, 1, 12]|
| 0,1,13|[0, 1, 13]|
| 0,1,14|[0, 1, 14]|
| 0,1,15|[0, 1, 15]|
| 0,1,16|[0, 1, 16]|
| 0,1,17|[0, 1, 17]|
| 0,1,18|[0, 1, 18]|
| 0,1,19|[0, 1, 19]|
| 0,1,20|[0, 1, 20]|
| 0,1,21|[0, 1, 21]|
+---------+----------+
only showing top 20 rows