Pyspark:从列表的RDD创建一个spark数据帧,其中列表的某些元素是对象

时间:2018-04-06 19:37:12

标签: python pandas apache-spark pyspark rdd

我正在尝试将pandas.DataFrame代码转换为等效的pyspark DataFrame。 我有一个以下格式的RDD。

myRdd = [[1, 'a', {'a':[1, 2]}],
         [2, 'b', {'c': 1, 'd':3}],
         [3, 'c', {}]]

columnNames = ['sl', 'name', 'params']

内部列表中的第三个元素没有特定的结构。 在pandas数据框中,我可以将第三列视为dtype = object。

pdDF = pandas.DataFrame(myRdd, columns=columnNames)

我可以做类似的事情,将上述格式的pyspark RDD转换为pyspark DataFrame吗?

1 个答案:

答案 0 :(得分:0)

Spark中没有dtype=object,但您可以定义自定义架构,将rdd转换为DataFrame,并将params列设为StructType()。您无法使用MapType(),因为所有键的值必须相同。

例如:

myRdd = [[1, 'a', {'a':[1, 2]}],
         [2, 'b', {'c': 1, 'd':3}],
         [3, 'c', {}]]

schema = StructType(
    [
        StructField('sl', IntegerType()),
        StructField('name', StringType()),
        StructField(
            'params',
            StructType(
                [
                    StructField('a', ArrayType(IntegerType())),
                    StructField('c', IntegerType()),
                    StructField('d', IntegerType())
                ]
            )
        )
    ]
)

rdd = sc.parallelize(myRdd)
df = rdd.toDF(schema)
df.show()
#+---+----+------------------------------+
#|sl |name|params                        |
#+---+----+------------------------------+
#|1  |a   |[WrappedArray(1, 2),null,null]|
#|2  |b   |[null,1,3]                    |
#|3  |c   |[null,null,null]              |
#+---+----+------------------------------+

然后,要访问特定元素,您可以使用getItem()方法或在选择中使用"."。例如,要为每行提取键"a"的值,您可以执行以下任一操作:

import pyspark.sql.functions as f
df.select("sl", "name", f.col("params").getItem("a")).show()
#+---+----+--------+
#| sl|name|params.a|
#+---+----+--------+
#|  1|   a|  [1, 2]|
#|  2|   b|    null|
#|  3|   c|    null|
#+---+----+--------+

df.select("sl", "name", "params.a").show()
#+---+----+------+
#| sl|name|     a|
#+---+----+------+
#|  1|   a|[1, 2]|
#|  2|   b|  null|
#|  3|   c|  null|
#+---+----+------+

或者您可以使用".*"作为单独的列访问所有元素:

df.select("sl", "name", "params.*").show()
#+---+----+------+----+----+
#| sl|name|     a|   c|   d|
#+---+----+------+----+----+
#|  1|   a|[1, 2]|null|null|
#|  2|   b|  null|   1|   3|
#|  3|   c|  null|null|null|
#+---+----+------+----+----+

DataFrame的架构是:

df.printSchema()
#root
# |-- sl: integer (nullable = true)
# |-- name: string (nullable = true)
# |-- params: struct (nullable = true)
# |    |-- a: array (nullable = true)
# |    |    |-- element: integer (containsNull = true)
# |    |-- c: integer (nullable = true)
# |    |-- d: integer (nullable = true)

这意味着,结构的特定成员的数据类型必须始终相同 - 例如,params.a必须是每行的整数列表。