繁体   English   中英

在 Apache Spark 中将 Dataframe 的列值提取为 List

[英]Extract column values of Dataframe as List in Apache Spark

我想将数据框的字符串列转换为列表。 我可以从Dataframe API 中找到 RDD,所以我尝试先将其转换回 RDD,然后将toArray函数应用于 RDD。 在这种情况下,长度和 SQL 工作得很好。 然而,我从 RDD 得到的结果在每个元素周围都有方括号[A00001] 我想知道是否有适当的方法将列转换为列表或删除方括号的方法。

任何建议,将不胜感激。 谢谢!

这应该返回包含单个列表的集合:

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

如果没有映射,您只会得到一个 Row 对象,其中包含数据库中的每一列。

请记住,这可能会为您提供 Any 类型的列表。 Ï如果要指定结果类型,可以在r => r(0).asInstanceOf[YOUR_TYPE]映射中使用r => r(0).asInstanceOf[YOUR_TYPE]

PS 由于自动转换,您可以跳过.rdd部分。

使用 Spark 2.x 和 Scala 2.11

我会想到 3 种可能的方法将特定列的值转换为 List。

所有方法的通用代码片段

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()向 Driver 收集数据并从每条记录中选取元素零。

这不是一个很好的方法,让我们用下一个方法改进它。


方法二

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 ,由于 DataFrame 中的编码器问题,它不会接受r => r(0) (或_(0) )作为以前的方法。 所以最终使用r => r.getString(0)并且它将在下一版本的 Spark 中解决。

结论

所有选项都给出相同的输出,但 2 和 3 是有效的,最后第三个是有效和优雅的(我认为)。

Databricks 笔记本

我知道给出和要求的答案是针对 Scala 的,所以我只是提供了一小段 Python 代码,以防 PySpark 用户好奇。 语法类似于给定的答案,但要正确弹出列表,我实际上必须在映射函数中再次引用列名,并且不需要 select 语句。

即一个 DataFrame,包含一个名为“Raw”的列

要将“Raw”中的每一行值组合为一个列表,其中每个条目都是“Raw”中的一个行值,我只需使用:

MyDataFrame.rdd.map(lambda x: x.Raw).collect()

在 Scala 和 Spark 2+ 中,试试这个(假设你的列名是“s”): df.select('s).as[String].collect

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

它完美地工作

from pyspark.sql.functions import col

df.select(col("column_name")).collect()

这里 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)中给出任何解决方案,以后可以感谢我

下面是 Python-

df.select("col_name").rdd.flatMap(lambda x: x).collect()

为您提供列表的更新解决方案:

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

这是Java答案。

df.select("id").collectAsList();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM