我已经在网上看了一些问题,但它们似乎没有达到我想要达到的效果。
我使用的是带有Scala的ApacheSpark 2.0.2。
我有一个数据框:
+----------+-----+----+----+----+----+----+
|segment_id| val1|val2|val3|val4|val5|val6|
+----------+-----+----+----+----+----+----+
| 1| 100| 0| 0| 0| 0| 0|
| 2| 0| 50| 0| 0| 20| 0|
| 3| 0| 0| 0| 0| 0| 0|
| 4| 0| 0| 0| 0| 0| 0|
+----------+-----+----+----+----+----+----+
我想把它换成
+----+-----+----+----+----+
|vals| 1| 2| 3| 4|
+----+-----+----+----+----+
|val1| 100| 0| 0| 0|
|val2| 0| 50| 0| 0|
|val3| 0| 0| 0| 0|
|val4| 0| 0| 0| 0|
|val5| 0| 20| 0| 0|
|val6| 0| 0| 0| 0|
+----+-----+----+----+----+
我试过使用pivot()
,但我找不到正确的答案。我最终遍历了val{x}
列,并按照下面的方式旋转每个列,但这被证明是非常慢的。
val d = df.select('segment_id, 'val1)
+----------+-----+
|segment_id| val1|
+----------+-----+
| 1| 100|
| 2| 0|
| 3| 0|
| 4| 0|
+----------+-----+
d.groupBy('val1).sum().withColumnRenamed('val1', 'vals')
+----+-----+----+----+----+
|vals| 1| 2| 3| 4|
+----+-----+----+----+----+
|val1| 100| 0| 0| 0|
+----+-----+----+----+----+
然后在val{x}
到我的第一个 Dataframe 的每次迭代中使用union()
。
+----+-----+----+----+----+
|vals| 1| 2| 3| 4|
+----+-----+----+----+----+
|val2| 0| 50| 0| 0|
+----+-----+----+----+----+
在我不想聚合数据的情况下,有没有更有效的转置方法?
谢谢:)
4条答案
按热度按时间rbl8hiat1#
不幸的是,没有下列情况:
DataFrame
是合理的。您必须记住,在Spark中实现的
DataFrame
是行的分布式集合,每行都在单个节点上存储和处理。您可以将
DataFrame
上的转置表示为pivot
:但它只是一个没有实际应用的玩具代码。实际上,它并不比收集数据更好:
对于
DataFrame
,定义为:两者都会给你想要的结果:
也就是说,如果您需要在分布式数据结构上进行有效的换位,您必须寻找其他地方。有许多结构,包括核心
CoordinateMatrix
和BlockMatrix
,它们可以跨两个维度分布数据,并且可以转置。gcuhipw92#
在Python中,这可以通过一种简单的方式来完成,我通常在Pandas中通过转换Spark DataFrame来使用转置函数
Spark_df.toPandas().T
bd1hkmkf3#
以下是PySpark的解决方案https://spark.apache.org/docs/latest/api/python/reference/pyspark.pandas/api/pyspark.pandas.DataFrame.transpose.html
以下是您的问题的解决方案代码:
步骤1:选择列
此代码部分可以形成如下数据框:
第二步:把整张table调换一下。
此代码部分可以形成如下数据框:
步骤3:需要将
segment_id
重命名为vals
:以下是您的完整代码:
sqxo8psd4#
这应该是一个完美的解决方案。