首页 文章

如何用新列覆盖Spark数据帧中的整个现有列?

提问于
浏览
3

我想用一个新的列覆盖一个spark列,这是一个二进制标志 .

我尝试直接覆盖列id2,但为什么它不像Pandas中的inplace操作那样工作?

如何在不使用withcolumn()创建新列和drop()来删除旧列的情况下执行此操作?

我知道spark数据帧是不可变的,这是因为没有使用withcolumn()&drop()而有不同的覆盖方式?

df2 = spark.createDataFrame(
        [(1, 1, float('nan')), (1, 2, float(5)), (1, 3, float('nan')), (1, 4, float('nan')), (1, 5, float(10)), (1, 6, float('nan')), (1, 6, float('nan'))],
        ('session', "timestamp1", "id2"))

    df2.select(df2.id2 > 0).show()

+---------+
|(id2 > 0)|
+---------+
|     true|
|     true|
|     true|
|     true|
|     true|
|     true|
|     true|
+---------+
 # Attempting to overwriting df2.id2
    df2.id2=df2.select(df2.id2 > 0).withColumnRenamed('(id2 > 0)','id2')
    df2.show()
#Overwriting unsucessful
+-------+----------+----+
|session|timestamp1| id2|
+-------+----------+----+
|      1|         1| NaN|
|      1|         2| 5.0|
|      1|         3| NaN|
|      1|         4| NaN|
|      1|         5|10.0|
|      1|         6| NaN|
|      1|         6| NaN|
+-------+----------+----+

3 回答

  • 1

    您可以使用

    d1.withColumnRenamed("colName", "newColName")
    d1.withColumn("newColName", $"colName")
    

    withColumnRenamed 将现有列重命名为新名称

    withColumn 创建一个具有给定名称的新列 . 如果已存在,则会创建一个具有相同名称的新列,并删除旧列 .

    在您的情况下,它不会在原始数据帧中更改df2它会更改列的名称并作为新数据帧返回,该数据帧应分配给新变量以供进一步使用 .

    `d3 = df2.select((df2.id2 > 0).alias("id2")`
    

    在你的情况下应该工作正常

    希望这可以帮助!

  • 6

    如上所述,不可能覆盖DataFrame对象,这是不可变集合,因此所有转换都返回新的DataFrame .

    实现所需效果的最快方法是使用 withColumn

    df = df.withColumn("col", some expression)
    

    其中 col 是您想要"replace"的列的名称 . 运行后, df 变量的值将被新的DataFrame替换为新的列 col . 您可能希望将此分配给新变量 .

    在你的情况下它可以看起来:

    df2 = df2.withColumn("id2", (df2.id2 > 0) & (df2.id2 != float('nan')))
    

    我已经将比较添加到 nan ,因为我想 nan 将大于0视为 nan .

  • 1

    如果您在不同的连接表中使用同名的多个列,则可以使用withColumn中colName中的表别名 .

    例如 . df1.join(df2, df1.id = df2.other_id).withColumn('df1.my_col', F.greatest(df1.my_col, df2.my_col))

    如果你只想保留df1中的列,你也可以调用 .select('df1.*')

    如果你做了 df1.join(df2, df1.id = df2.other_id).withColumn('my_col', F.greatest(df1.my_col, df2.my_col))

    我认为它会覆盖最后一列名为my_col的列 . 所以输出: id, my_col (df1.my_col original value), id, other_id, my_col (newly computed my_col)

相关问题