首页 > 解决方案 > 如何在 Pyspark 中保持其余数据框相同的同时转换一列数据框?

问题描述

例如,我有一个数据框

df.show()
+---+-----+
|age| name|
+---+-----+
|  1|Alice|
|  2|  Bob|
|  4| Bill|
+---+-----+ 

现在我想以这样一种方式进行转换,即名称列变为结构类型,其中包含两列“name_id”,现在所有值都可以为 0,“name_text”是名称列中的值。注意:df 可以改变。所以我不能硬编码模式。它必须是动态的。所以例如,如果我需要一个这样的功能

func(df)

应该给出一个 df 作为

+---+---------+
|age|     name|
+---+---------+
|  1|[0,Alice]|
|  2|  [0,Bob]|
|  4| [0,Bill]|
+---+---------+

这将是一个巨大的帮助,谢谢。

标签: pythonapache-sparkpyspark

解决方案


def generate_intial_transform_schema(df,column_id):
    index= 0
    schemaList = []
    for schema in df.schema:
        if index == column_id:
            schemaList.append(
            StructField(schema.name,StructType([
                StructField("value",schema.dataType,schema.nullable),
                StructField("id",schema.dataType,True),
                ]),True))
        else:
            schemaList.append(schema)
        index += 1
    generated_schema = StructType(schemaList)
    return generated_schema

def intial_transform(lines,column_id):

    return_touple = ()
    for i in range(0,len(df.columns)):
        if i!= column_id:
            return_touple = return_touple+(lines[i],)
        else:
            return_touple = return_touple+((lines[i],1),)
    return return_touple

所以,你调用 map 函数

df2 = df1.rdd.map(
lambda lines:intial_transform(lines,1)
).toDF(
generate_intial_transform_schema(lines,1)
)

推荐阅读