PySpark中如何将原DataFrame列名与数据类型转为新DataFrame的两列?
问题分析与解决方案
错误原因解析
1. ValueError错误
你构建的data = [[row_rdd_col_names], [row_rdd_col_types]]结构完全不符合Spark创建DataFrame的要求:
- 你的schema定义了2列,意味着每一行数据必须包含2个对应的值
- 但你传入的是一个二维列表,每个子列表仅包含1个RDD对象,每个行的元素数量(1)和schema的字段数量(2)不匹配,直接触发长度不匹配的ValueError
2. 空值结果问题
当你改为data = [(row_rdd_col_names), (row_rdd_col_types)]时:
- 你把两个RDD对象直接当作行数据传入,Spark无法将RDD对象解析成
StringType的列值,因此所有字段显示为null - 这种写法最终只会生成2行数据,完全不符合你需要的88行(对应原DF的88列)的预期
正确实现方法
其实不需要拆分RDD再合并,User_df.dtypes本身就是一个包含(列名, 数据类型)元组的列表,直接用它创建DataFrame即可,代码极简:
from pyspark.sql.types import StructType, StructField, StringType # 用原DataFrame的dtypes列表创建新DF,手动指定schema schema = StructType([ StructField("ColumnNames", StringType(), True), StructField("ColumnDataTypes", StringType(), True) ]) new_dataframe = sqlContext.createDataFrame(User_df.dtypes, schema) new_dataframe.show()
或者更简洁的方式,无需手动定义schema(Spark会自动推断元组结构):
# 自动推断schema,直接指定列名 new_dataframe = sqlContext.createDataFrame(User_df.dtypes, ["ColumnNames", "ColumnDataTypes"]) new_dataframe.show()
简化版单类型列生成(补充)
你之前单独生成数据类型列的代码可以大幅简化,无需操作RDD:
# 提取所有数据类型并生成单列表DF type_list = [t for (_, t) in User_df.dtypes] new_dataframe = sqlContext.createDataFrame(type_list, ["ColumnDataTypes"]) new_dataframe.show()
内容的提问来源于stack exchange,提问作者JTD2021
相关产品推荐
相关产品推荐

