web-dev-qa-db-ja.com

Apache SparkでDataframeの列値をリストとして抽出する

データフレームの文字列列をリストに変換したいのですが。 Dataframe APIから見つけることができるのはRDDなので、まずそれをRDDに変換し直してから、toArray関数をRDDに適用します。この場合、長さとSQLは問題なく機能します。しかし、私がRDDから得た結果は、この[A00001]のようにすべての要素を角括弧で囲んでいます。列をリストに変換するための適切な方法、または角括弧を削除するための方法があるかどうか疑問に思いました。

任意の提案は大歓迎です。ありがとうございました!

66
SH Y.

これは単一のリストを含むコレクションを返すはずです:

dataFrame.select("YOUR_COLUMN_NAME").rdd.map(r => r(0)).collect()

マッピングがなければ、データベースのすべての列を含むRowオブジェクトを取得するだけです。

これはおそらくあなたにAnyタイプのリストを与えるだろうということを覚えておいてください。結果タイプを指定したい場合は、r => r(0).asInstanceOf[YOUR_TYPE]マッピングで.asInstanceOf [YOUR_TYPE]を使用できます。

P.S自動変換のため、.rdd部分をスキップすることができます。

89
Niemand

Spark 2.xとScala 2.11を使って

特定の列の値をListに変換する3つの方法が考えられます。

すべてのアプローチに共通のコードスニペット

import org.Apache.spark.sql.SparkSession

val spark = SparkSession.builder.getOrCreate    
import spark.implicits._ // for .toDf() method

val df = Seq(
    ("first", 2.0),
    ("test", 1.5),
    ("choose", 8.0)
  ).toDF("id", "val")

アプローチ1

df.select("id").collect().map(_(0)).toList
// res9: List[Any] = List(one, two, three)

今、何が起きた? collect()を使用してDriverにデータを収集し、各レコードから要素ゼロを選択します。

これはそれを行うための優れた方法ではありませんでした、次のアプローチでそれを改善しましょう。


アプローチ2

df.select("id").rdd.map(r => r(0)).collect.toList 
//res10: List[Any] = List(one, two, three)

どうですか?私たちは単一の運転手ではなく作業者の間で地図変換の負荷を分散させました。

rdd.map(r => r(0))はあなたにとって優雅ではないようです。それでは、次のアプローチでそれを取り上げましょう


アプローチ3

df.select("id").map(r => r.getString(0)).collect.toList 
//res11: List[String] = List(one, two, three)

ここではDataFrameをRDDに変換していません。 DataFrameのエンコーダの問題のため、以前のアプローチとしてmapを見てもr => r(0)(または_(0))は受け入れられません。そのため、r => r.getString(0)を使用することになり、Sparkの次のバージョンで対処されるでしょう。

結論

すべてのオプションで同じ出力が得られますが、2と3が効果的で、最後に3番目のものが効果的でエレガントです(私は思います)。

2017/05/20から6ヶ月まで利用できるようになるDatabricksノートブックリンク

42
mrsrinivas

私は与えられたそして求められた答えがScalaのために仮定されているのを知っているので、私はPySparkユーザーが興味を持った場合に備えてPythonコードの小さな断片を単に提供しています。構文は与えられた答えに似ていますが、リストを正しくポップするためには、実際にはマッピング関数で2回目に列名を参照する必要があり、selectステートメントは必要ありません。

すなわち、 "Raw"という名前の列を含むDataFrame

"Raw"の各行の値が "Raw"の行の値であるリストとして結合するには、単に次のようにします。

MyDataFrame.rdd.map(lambda x: x.Raw).collect()
15
abby sobh

ScalaとSpark 2+では、これを試してください(あなたのカラム名が "s"であると仮定して):df.select('s).as[String].collect

4
kanielc
     sqlContext.sql(" select filename from tempTable").rdd.map(r => r(0)).collect.toList.foreach(out_streamfn.println) //remove brackets

それは完璧に動作します

1
Shaina Raza