假设,我有以下数据帧:
id | col1 | col2
-----------------
x | p1 | a1
-----------------
x | p2 | b1
-----------------
y | p2 | b2
-----------------
y | p2 | b3
-----------------
y | p3 | c1
与 col1 不同的值(p1、p2、p3)单独具有 id,将用作最终数据帧的列。在这里,id y 对于相同的 col1 值 p2 有两个 col2 值(b2 和 b3),因此,p2 将被视为数组类型列。因此,最终的数据帧将是
id | p1 | p2 | p3
--------------------------------
x | a1 | [b1] | null
--------------------------------
y | null |[b2, b3]| c1
如何从第一个数据帧高效地实现第二个数据帧?
您基本上是在寻找表数据透视;对于您的情况,groupBy
id
,pivot
col1作为头,并使用<code>collect_list聚合为列表:
df.groupBy("id").pivot("col1").agg(collect_list("col2")).show
+---+----+--------+----+
| id| p1| p2| p3|
+---+----+--------+----+
| x|[a1]| [b1]| []|
| y| []|[b2, b3]|[c1]|
+---+----+--------+----+
如果保证每个< code>id在< code>p1和< code>p3中最多有一个值,您可以通过< code >获取数组的第一项将这些列转换为字符串类型:
df.groupBy("id").pivot("col1").agg(collect_list("col2"))
.withColumn("p1", $"p1"(0)).withColumn("p3", $"p3"(0))
.show
+---+----+--------+----+
| id| p1| p2| p3|
+---+----+--------+----+
| x| a1| [b1]|null|
| y|null|[b2, b3]| c1|
+---+----+--------+----+
如果您需要动态转换列类型,即仅在必要时使用数组类型列类型:
// get array Type columns
val arrayColumns = df.groupBy("id", "col1").agg(count("*").as("N"))
.where($"N" > 1).select("col1").distinct.collect.map(row => row.getString(0))
// arrayColumns: Array[String] = Array(p2)
// aggregate / pivot data frame
val aggDf = df.groupBy("id").pivot("col1").agg(collect_list("col2"))
// aggDf: org.apache.spark.sql.DataFrame = [id: string, p1: array<string> ... 2 more fields]
// get string columns
val stringColumns = aggDf.columns.filter(x => x != "id" && !arrayColumns.contains(x))
// use foldLeft on string columns to convert the columns to string type
stringColumns.foldLeft(aggDf)((df, x) => df.withColumn(x, col(x)(0))).show
+---+----+--------+----+
| id| p1| p2| p3|
+---+----+--------+----+
| x| a1| [b1]|null|
| y|null|[b2, b3]| c1|
+---+----+--------+----+
我正在尝试查看我们是否可以使用 spark/scala 从 dataFrame 中某个列中的值创建新列。我有一个数据帧,其中包含以下数据 在上面的数据中,col1/col2/col3是列名,后跟它的值。列名和值由< code >,分隔。每组由< code>|分隔。 现在,我想做到这一点 感谢任何帮助。
我正在尝试在 pyspark 中连接两个数据帧,但将一个表作为数组列连接在另一个表上。 例如,对于这些表: 我想在列和上将df1连接到df2,但和应该是单个数组类型列。此外,应保留所有名称。新数据框的输出应该能够转换为此json结构(例如前两行): 任何关于如何实现这一目标的想法都将不胜感激! 谢谢, 卡罗莱纳州
我不是本地JAVA程序员。我正在为web服务API创建一个客户端。API基本上需要一个数组参数。 我正在解析一个XML文件,创建记录,然后使用此API进行批量插入。 问题是这个API一次只能插入200条记录,这意味着我的数组在调用时只能有200条或更少的记录。 由于我不知道预先有多少条记录,所以我将我的记录存储在ArrayList中,然后使用将其转换为Array。ToArray() 现在,由于AP
我正在改装一些现有代码以使用Spark。我有多个包含不同数据集的数据帧。在转换主数据帧(或主数据集)时,我需要使用来自其他数据帧的数据来完成转换。我还有一种情况(至少在当前结构中),我需要在另一个数据帧的转换函数中创建新的数据帧。 我试图确定以下内容: 我可以在另一个数据帧的转换函数中访问数据帧吗 关于如何处理这种情况的指针将非常有帮助。
我和Spark一起在Databricks上工作。编程语言是Scala。 我有两个数据帧: 主数据框:见截图:1 查找数据帧:参见屏幕截图3 我想: 查找主数据框中“年龄”=-1的所有行 我对如何做这件事伤了脑筋。我唯一想到的是将dataframe存储为DataRicks中的表,并使用SQL语句(SQL.Context.SQL…),结果非常复杂。 我想知道是否有更有效的方法。 编辑:添加可复制的示例
我得到以下错误:org.apache.spark.sql.analysisException:不允许在另一个聚合函数的参数中使用聚合函数。请在子查询中使用内部聚合函数。;; 我尝试了多种解决方案来解决这个问题,但似乎没有任何效果。所有的想法都得到了赞赏。谢了!