我想用一个新的列覆盖一个spark列,这是一个二进制标志。
我尝试直接覆盖列id2,但为什么它不像Pandas中的inplace操作那样工作?
如何在不使用withcolumn()创建新列和drop()来删除旧列的情况下执行此操作?
我知道spark数据帧是不可变的,是因为没有使用withcolumn()&的原因或者有不同的覆盖方式降()?
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|
+-------+----------+----+
答案 0 :(得分:9)
您可以使用
d1.withColumnRenamed("colName", "newColName")
d1.withColumn("newColName", $"colName")
withColumnRenamed
将现有列重命名为新名称
withColumn
创建一个具有给定名称的新列。如果已存在,则会创建一个具有相同名称的新列,并删除旧列。
在你的情况下,它不会改变原始数据框df2它会更改列的名称并作为新数据帧返回,应该将其分配给新变量以供进一步使用。
`d3 = df2.select((df2.id2 > 0).alias("id2")`
在你的情况下应该可以正常工作
希望这有帮助!
答案 1 :(得分:3)
如上所述,不可能覆盖DataFrame对象,这是不可变的集合,因此所有转换都返回新的DataFrame。
达到预期效果的最快方法是使用withColumn
:
df = df.withColumn("col", some expression)
其中col
是您要“替换”的列的名称。运行后,df
变量的值将被新的DataFrame替换为新值col
。您可能希望将其分配给新变量。
在你的情况下它可以看起来:
df2 = df2.withColumn("id2", (df2.id2 > 0) & (df2.id2 != float('nan')))
我已添加与nan
的比较,因为我假设您不希望将nan
视为大于0。
答案 2 :(得分:1)
如果您正在使用不同连接表中的多个同名列,则可以使用withColumn中colName中的表别名。
EG。 image_data
如果你只想保留df1中的列,你也可以调用df1.join(df2, df1.id = df2.other_id).withColumn('df1.my_col', F.greatest(df1.my_col, df2.my_col))
如果您改为.select('df1.*')
我认为它会覆盖最后一列名为my_col的列。所以输出:
df1.join(df2, df1.id = df2.other_id).withColumn('my_col', F.greatest(df1.my_col, df2.my_col))