1

我想覆蓋一個新的列是一個二進制標誌的火花列。如何用新列覆蓋Spark數據框中的整個現有列?

我試着直接覆蓋列id2,但爲什麼它不像Pandas中的就地操作?

如何在不使用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| 
+-------+----------+----+ 
+0

星星之火可以」像熊貓這樣寫就地,如果這是你正在尋找。數據幀是不可變的結構,它們不能被覆蓋。 – eliasah

回答

2

您可以使用

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

withColumnRenamed重命名現有列,以新名稱

withColumn創建一個具有給定名稱的新列。如果已經存在並刪除舊列,它將創建一個具有相同名稱的新列。

在你的情況下,它在原始數據幀df2中沒有改變,它改變了列的名稱並返回一個新的數據幀,該數據幀應被分配給新的變量以供進一步使用。

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

應該能正常運行,你的情況

希望這有助於!

+0

我希望這可以消除你的困惑。 –

1

如上所述,不可能覆蓋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

+0

id2列最初存在於df2中。因此,當我們嘗試使用withColumn()在現有名稱id2中創建df2中的新列時,爲什麼它不會拋出衝突錯誤,指出「id2已經存在以至於無法更改」或者因爲dataframe是不可變的?請解釋這一點,如何withcolumn()的作品 –

+1

withColumn()如果列已經存在,如果列中存在不拋出異常,則丟棄舊列並創建變更數據的新列。 –

相關問題