将pyspark Row列表的RDD转换为DataFrame

4

我有一个RDD,其分区包含元素(恰好是pandas数据帧),可以轻松地转换为行的列表。想象一下它看起来像这样:

rows_list = []
for word in 'quick brown fox'.split():
    rows = []
    for i,c in enumerate(word):
        x = ord(c) + i
        row = pyspark.sql.Row(letter=c, number=i, importance=x)
        rows.append(row)
    rows_list.append(rows)
rdd = sc.parallelize(rows_list)
rdd.take(2)

这提供了

[[Row(importance=113, letter='q', number=0),
  Row(importance=118, letter='u', number=1),
  Row(importance=107, letter='i', number=2),
  Row(importance=102, letter='c', number=3),
  Row(importance=111, letter='k', number=4)],
 [Row(importance=98, letter='b', number=0),
  Row(importance=115, letter='r', number=1),
  Row(importance=113, letter='o', number=2),
  Row(importance=122, letter='w', number=3),
  Row(importance=114, letter='n', number=4)]]

我想将它转换为Spark DataFrame。我希望只需执行以下操作:
rdd.toDF()

但这会产生无用的结构

DataFrame[_1: struct<importance:bigint,letter:string,number:bigint>,
          _2: struct<importance:bigint,letter:string,number:bigint>,
          _3: struct<importance:bigint,letter:string,number:bigint>, 
          _4: struct<importance:bigint,letter:string,number:bigint>, 
          _5: struct<importance:bigint,letter:string,number:bigint>]

我真正想要的是一个3列的DataFrame,就像这样

desired_df = sql_context.createDataFrame(sum(rows_list, []))

这样我就可以执行像以下这样的操作:

desired_df.agg(pyspark.sql.functions.sum('number')).take(1)

并得到答案23。

如何正确处理这个问题?

1个回答

5

您有一组列表的RDD,而需要的是行的RDD;您可以使用flatMaprdd扁平化,然后将其转换为数据帧:

rdd.flatMap(lambda x: x).toDF().show()

+----------+------+------+
|importance|letter|number|
+----------+------+------+
|       113|     q|     0|
|       118|     u|     1|
|       107|     i|     2|
|       102|     c|     3|
|       111|     k|     4|
|        98|     b|     0|
|       115|     r|     1|
|       113|     o|     2|
|       122|     w|     3|
|       114|     n|     4|
|       102|     f|     0|
|       112|     o|     1|
|       122|     x|     2|
+----------+------+------+

import pyspark.sql.functions as F

rdd.flatMap(lambda x: x).toDF().agg(F.sum('number')).show()
+-----------+
|sum(number)|
+-----------+
|         23|
+-----------+

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接