簡體   English   中英

在 spark 中更新數據框列

[英]Updating a dataframe column in spark

查看新的spark dataframe api,不清楚是否可以修改dataframe列。

我將如何更改數據框第xy中的值?

pandas這將是df.ix[x,y] = new_value

編輯:合並下面所說的內容,您不能修改現有數據幀,因為它是不可變的,但您可以返回一個具有所需修改的新數據幀。

如果您只想根據條件替換列中的值,例如np.where

from pyspark.sql import functions as F

update_func = (F.when(F.col('update_col') == replace_val, new_value)
                .otherwise(F.col('update_col')))
df = df.withColumn('new_column_name', update_func)

如果要對列執行某些操作並創建添加到數據框中的新列:

import pyspark.sql.functions as F
import pyspark.sql.types as T

def my_func(col):
    do stuff to column here
    return transformed_value

# if we assume that my_func returns a string
my_udf = F.UserDefinedFunction(my_func, T.StringType())

df = df.withColumn('new_column_name', my_udf('update_col'))

如果您希望新列與舊列具有相同的名稱,您可以添加額外的步驟:

df = df.drop('update_col').withColumnRenamed('new_column_name', 'update_col')

雖然您不能像這樣修改列,但您可以對列進行操作並返回一個反映該更改的新 DataFrame。 為此,您首先要創建一個UserDefinedFunction實現要應用的操作,然后有選擇地將該函數僅應用於目標列。 在 Python 中:

from pyspark.sql.functions import UserDefinedFunction
from pyspark.sql.types import StringType

name = 'target_column'
udf = UserDefinedFunction(lambda x: 'new_value', StringType())
new_df = old_df.select(*[udf(column).alias(name) if column == name else column for column in old_df.columns])

new_df現在具有與相同的模式old_df (假設old_df.target_column是類型的StringType以及),但在列中的所有值target_columnnew_value

通常在更新列時,我們希望將舊值映射到新值。 這是在沒有 UDF 的 pyspark 中執行此操作的一種方法:

# update df[update_col], mapping old_value --> new_value
from pyspark.sql import functions as F
df = df.withColumn(update_col,
    F.when(df[update_col]==old_value,new_value).
    otherwise(df[update_col])).

DataFrames基於 RDD。 RDD 是不可變的結構,不允許在現場更新元素。 要更改值,您需要通過使用類似 SQL 的 DSL 或 RDD 操作(例如map轉換原始數據幀來創建新的數據幀。

強烈推薦的幻燈片: Introducing DataFrames in Spark for Large Scale Data Science

正如maasg所說,您可以根據應用於舊 DataFrame 的地圖的結果創建新的 DataFrame。 具有兩行的給定 DataFrame df的示例:

val newDf = sqlContext.createDataFrame(df.map(row => 
  Row(row.getInt(0) + SOMETHING, applySomeDef(row.getAs[Double]("y")), df.schema)

請注意,如果列的類型發生變化,則需要為其提供正確的架構而不是df.schema 查看org.apache.spark.sql.Row的 api 以獲取可用方法: https : //spark.apache.org/docs/latest/api/java/org/apache/spark/sql/Row.html

[更新] 或者在 Scala 中使用 UDF:

import org.apache.spark.sql.functions._

val toLong = udf[Long, String] (_.toLong)

val modifiedDf = df.withColumn("modifiedColumnName", toLong(df("columnName"))).drop("columnName")

如果列名需要保持不變,您可以將其重命名:

modifiedDf.withColumnRenamed("modifiedColumnName", "columnName")

導入col,當pyspark.sql.functions並根據 string(string a, string b, string c) 將第五列更新為 integer(0,1,2) 到新的 DataFrame 中時。

from pyspark.sql.functions import col, when 

data_frame_temp = data_frame.withColumn("col_5",when(col("col_5") == "string a", 0).when(col("col_5") == "string b", 1).otherwise(2))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM