2017-12-27 39 views
0

データフレームの行を列に転記する方法はありますか。 私は、入力としての構造を以下している:列に行を入れ替えるために利用可能な任意の最適化された直接のAPIがある場合spark datframe、scalaの行を列に変換する方法

val inputDF = Seq(("pid1","enc1", "bat"),("pid1","enc2", ""),("pid1","enc3", ""),("pid3","enc1", "cat"),("pid3","enc2", "")).toDF("MemberID", "EncounterID", "entry") 

inputDF.show: 

+--------+-----------+-----+ 
|MemberID|EncounterID|entry| 
+--------+-----------+-----+ 
| pid1|  enc1| bat| 
| pid1|  enc2|  | 
| pid1|  enc3|  | 
| pid3|  enc1| cat| 
| pid3|  enc2|  | 
+--------+-----------+-----+ 

expected result: 

+--------+----------+----------+----------+-----+ 
|MemberID|Encounter1|Encounter2|Encounter3|entry| 
+--------+----------+----------+----------+-----+ 
| pid1|  enc1|  enc2|  enc3| bat| 
| pid3|  enc1|  enc2|  null| cat| 
+--------+----------+----------+----------+-----+ 

示唆してください。 私の入力データサイズはかなり大きいので、collectのようなアクションはドライバのすべてのデータを取るので実行できません。 私はSpark 2.xを使用しています

+0

'entry'がすべて3 EncounterID'の値を持っていたらどうなりますか? 'EncounterID'は3つしかありませんか? – philantrovert

+0

エントリの値は1つだけです。はいEncounterIDは固定ですが、EncounterIDは3つしかありません。 – Kalpesh

+1

これがあなたが期待している結果だと確信していますか? 3つのエンカウンター列は常に同じ値を持ちます... – Oli

答えて

0

私が必要とするものは実際に尋ねたものです。しかし、念のため、ここでアイデアです:

val entries = inputDF.where('entry isNotNull) 
    .where('entry !== "") 
    .select("MemberID", "entry").distinct 

val df = inputDF.groupBy("MemberID") 
    .agg(collect_list("EncounterID") as "encounterList") 
    .join(entries, Seq("MemberID")) 
df.show 
+--------+-------------------------+-----+ 
|MemberID|   encounterList |entry| 
+--------+-------------------------+-----+ 
| pid1|  [enc2, enc1, enc3]| bat| 
| pid3|    [enc2, enc1]| cat| 
+--------+-------------------------+-----+ 

リストの順序は決定的ではないですが、あなたはそれをソートし、その後.withColumn("Encounter1", sort_array($"encounterList")(0))で、そこから新しい列を抽出することができる...

その他のアイデア何をしたい場合には

あなたはピボットを使用することができ、対応する「出会い」の列にエントリの値を置くことです:

inputDF 
    .groupBy("MemberID") 
    .pivot("EncounterID", Seq("enc1", "enc2", "enc3")) 
    .agg(first("entry")).show 

+--------+----+----+----+ 
|MemberID|enc1|enc2|enc3| 
+--------+----+----+----+ 
| pid1| bat| | | 
| pid3| cat| | | 
+--------+----+----+----+ 

Seq("enc1", "enc2", "enc3")を追加するのはoptionnalですが、列の内容を知っているので計算が高速になります。

+0

です。申し訳ありませんが、値をハードコードすることはできません。私が追加したくないことがもう1つあります。特定のmemberIDに対して2行しか使用できない場合、コードは3列目をnullとしてマークできるはずです。 ..私は質問を更新する – Kalpesh

関連する問題