Pyspark - 从Str到Int转换多个列

时间:2017-04-24 15:31:15

标签: python apache-spark casting pyspark

我正在尝试使用PySpark 2.1.0将多个String列转换为数据框中的整数。数据集是一个开始的rdd,当创建为数据帧时,它会生成以下错误:

TypeError: StructType can not accept object 3 in type <class 'int'>

我正在尝试做的一个示例:

import pyspark.sql.types as typ
from pyspark.sql.functions import *

labels = [
    ('A', typ.StringType()),
    ('B', typ.IntegerType()),
    ('C', typ.IntegerType()),
    ('D', typ.IntegerType()),
    ('E', typ.StringType()),
    ('F', typ.IntegerType())
]

rdd = sc.parallelize(["1", 2, 3, 4, "5", 6])
schema = typ.StructType([typ.StructField(e[0], e[1], False) for e in labels])
df = spark.createDataFrame(rdd, schema)
df.show()

cols_to_cast = [dt[0] for dt in df.dtypes if dt[1]=='string']
#df2 = df.select(*(c.cast("integer").alias(c) for c in cols_to_cast))

df2 = df.select(*( df[dt[0]].cast("integer").alias(dt[0])
                        for dt in df.dtypes if dt[1]=='string'))

df2.show()

开始的问题是没有基于RDD创建数据帧。 此后,我尝试了两种投射方式(df2),第一种是注释掉的。

有什么建议吗? 或者,无论如何我可以使用.withColumn函数在1 go中转换所有列,而不是指定每列? 实际数据集虽然不大,却有很多列。

1 个答案:

答案 0 :(得分:1)

问题不是你的代码,而是你的数据。您正在传递单个列表,该列表将被视为单列而不是您想要的六个列。

尝试下面的rdd行,它应该可以正常工作。(注意列表周围的额外括号) -

rdd = sc.parallelize([["1", 2, 3, 4, "5", 6]]) 

您使用上面更正的代码显示以下输出:

+---+---+---+---+---+---+
|  A|  B|  C|  D|  E|  F|
+---+---+---+---+---+---+
|  1|  2|  3|  4|  5|  6|
+---+---+---+---+---+---+

+---+---+
|  A|  E|
+---+---+
|  1|  5|
+---+---+