【问题标题】:how to transform pyspark dataframe?如何转换pyspark数据框?
【发布时间】:2021-07-14 10:59:46
【问题描述】:

我必须对类似于 pandas transform 的 pyspark 数据帧执行转换操作。 通过对数据框应用 .summary() 操作,我得到了 pyspark-dataframe 以下。

value   col_a       col_b           col_c
count   14.000000   14.000000       14.000000   
mean    9.928571    3189.785714     155210.857143   
std     7.086979    1413.286904     76682.259154    
min     0.000000    0.000000        0.000000    
25%     5.500000    3152.500000     129994.750000   
50%     9.500000    3596.000000     158677.500000   
75%     12.500000   4007.250000     210596.750000   
max     23.000000   4543.000000     256496.000000   

我想将行转换为列,将列转换为行。如下所示

value   count   mean             std         min 25%        50%      75%         max
col_a   14.0    9.928571        7.086979     0.0  5.50      9.5      12.50      23.0
col_b   14.0    3189.785714     1413.286904  0.0  3152.50   3596.0   4007.25    4543.0
col_c   14.0    155210.857143   76682.259154 0.0  129994.75 158677.5 210596.75  256496.0

另外,transform 之前的列不固定。为了解释问题,我采用了 3 列 col_a、col_b、col_c。但在真实场景中,最高可达 10k。

在 pandas 中,我可以通过以下方式实现:-

     transformed_df = df.T

【问题讨论】:

  • 这能回答你的问题吗? stackoverflow.com/questions/46453058/…
  • 我的数据框非常庞大,要将其转换为 pandas,需要花费太多时间和资源。
  • 你为什么需要转置 - 我想知道你是否可以保持数据原样
  • 我想将它存储在蜂巢表上。正如我在转置之前提到的列大约 10K。这就是为什么我想先转置它并将它存储在一个只有 8 列的配置单元中。 @doctorlove
  • 这里可能有一些想法:stackoverflow.com/questions/36215755/…

标签: dataframe pyspark


【解决方案1】:

根据您的评论,由于枢轴不可用,我的替代解决方案有点冗长

cols = ['col_a', 'col_b', 'col_c']
metrics = ['count', 'mean', 'std', 'min', '25%', '50%', '75%', 'max']

(df
    .withColumn('keys', F.array([F.lit(c) for c in cols]))
    .withColumn('values', F.array([F.col(c) for c in cols]))
    .withColumn('maps', F.map_from_arrays('keys', 'values'))
    .select(F.col('value').alias('metric'), F.explode('maps').alias('col', 'value'))
    .groupBy('col')
    .agg(
        F.collect_list('metric').alias('keys'),
        F.collect_list('value').alias('values')
    )
    .withColumn('maps', F.map_from_arrays('keys', 'values'))
    .select(['col'] + [f'maps.{c}' for c in metrics])
    .show(10, False)
)

# Output
+-----+-----+-------------+------------+---+---------+--------+---------+--------+
|col  |count|mean         |std         |min|25%      |50%     |75%      |max     |
+-----+-----+-------------+------------+---+---------+--------+---------+--------+
|col_b|14.0 |3189.785714  |1413.286904 |0.0|3152.5   |3596.0  |4007.25  |4543.0  |
|col_c|14.0 |155210.857143|76682.259154|0.0|129994.75|158677.5|210596.75|256496.0|
|col_a|14.0 |9.928571     |7.086979    |0.0|5.5      |9.5     |12.5     |23.0    |
+-----+-----+-------------+------------+---+---------+--------+---------+--------+

【讨论】:

  • 感谢您的回答,但在 [f'maps.{c}' for c in metrics] 中给了我无效的语法错误。 @pltc
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-09
  • 2022-08-16
  • 1970-01-01
  • 2021-02-10
  • 2022-01-04
  • 1970-01-01
  • 2021-11-25
相关资源
最近更新 更多