データフレームの文字列列をリストに変換したい。Dataframe
APIからわかるのはRDDなので、まずRDDに変換してtoArray
から、RDDに関数を適用してみました。この場合、長さとSQLは問題なく機能します。ただし、RDDから取得した結果には、このようなすべての要素を角かっこで囲んでいます[A00001]
。列をリストに変換する適切な方法や、角かっこを削除する方法があるかどうか疑問に思いました。
任意の提案をいただければ幸いです。ありがとうございました!
回答:
これにより、単一のリストを含むコレクションが返されます。
dataFrame.select("YOUR_COLUMN_NAME").rdd.map(r => r(0)).collect()
マッピングがないと、データベースのすべての列を含むRowオブジェクトを取得するだけです。
これにより、おそらく任意のタイプのリストが表示されることに注意してください。結果タイプを指定する場合は、r => r(0).asInstanceOf[YOUR_TYPE]
マッピングで.asInstanceOf [YOUR_TYPE]を使用できます。
PS自動変換のため、.rdd
パーツをスキップできます。
collect().map(r => r(0))
-この順序には不利な点がありますか?
特定の列の値をリストに変換する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")
df.select("id").collect().map(_(0)).toList
// res9: List[Any] = List(one, two, three)
今、何が起きた?collect()
各レコードから要素ゼロを使用してドライバーにデータを収集しています。
これはそれを行うための優れた方法ではありませんでした。次のアプローチで改善しましょう。
df.select("id").rdd.map(r => r(0)).collect.toList
//res10: List[Any] = List(one, two, three)
どうですか?単一のドライバーではなく、ワーカー間でマップ変換の負荷を分散しました。
私rdd.map(r => r(0))
はあなたがエレガントに見えないことを知っています。それでは、次のアプローチで対処しましょう。
df.select("id").map(r => r.getString(0)).collect.toList
//res11: List[String] = List(one, two, three)
ここでは、DataFrameをRDDに変換していません。見てmap
、それは受け付けませんr => r(0)
(または_(0)
起因するデータフレーム内エンコーダの問題に以前のアプローチとして)。したがって、使用r => r.getString(0)
することになり、Sparkの次のバージョンで対処されることになります。
結論
すべてのオプションで同じ出力が得られますが、2と3が効果的で、最後に3番目のオプションが効果的でエレガントです(私は思います)。
私は与えられて求められた答えがScalaに想定されていることを知っているので、PySparkユーザーが興味を持っている場合に備えてPythonコードの小さなスニペットを提供しています。構文は与えられた答えに似ていますが、リストを適切にポップアウトするには、実際にはマッピング関数で列名をもう一度参照する必要があり、selectステートメントは必要ありません。
つまり、「Raw」という名前の列を含むDataFrame
「Raw」の各行の値をリストとして結合し、各エントリが「Raw」の行の値であるようにするには、次のようにします。
MyDataFrame.rdd.map(lambda x: x.Raw).collect()
List<String> whatever_list = df.toJavaRDD().map(new Function<Row, String>() {
public String call(Row row) {
return row.getAs("column_name").toString();
}
}).collect();
logger.info(String.format("list is %s",whatever_list)); //verification
java(Real Programming Language)で誰も解決策を与えていないので、後で私に感謝することができます
リストを取得する更新されたソリューション:
dataFrame.select("YOUR_COLUMN_NAME").map(r => r.getString(0)).collect.toList
以下はPython用です-
df.select("col_name").rdd.flatMap(lambda x: x).collect()