【问题标题】:Update pyspark dataframe column with complex function使用复杂函数更新 pyspark 数据框列
【发布时间】:2016-09-05 08:17:30
【问题描述】:

是否可以使用 UDF 中不可用的复杂函数更新 pyspark 中的 hiveContext 数据框列?

我有一个包含许多列的数据框,其中 2 列称为时间戳和数据。如果数据中的时间戳满足某些条件,我需要从数据中的 JSON 字符串中检索时间戳并更新时间戳列。我知道数据框是不可变的,但是可以以某种方式构建一个新的数据框,保留旧数据框的所有列但更新 timstamp 列?

说明我想做的代码:

def updateTime(row):
    import json

    THRESHOLD_TIME = 60 * 30
    client_timestamp = json.loads(row['data'])
    client_timestamp = float(client_timestamp['timestamp'])
    server_timestamp = float(row['timestamp'])
    if server_timestamp - client_timestamp <= THRESHOLD_TIME:
        new_row = .....  # copy contents of row
        new_row['timestamp'] = client_timestamp
        return new_row
    else:
        return row

df = df.map(updateTime)

我想过将行内容映射到元组,然后使用 .toDF() 将其转换回数据帧,但我找不到将行内容复制到元组然后取回列名的方法。

【问题讨论】:

  • 如果你使用UDF呢?
  • 或许这篇文章能帮上忙:sparktutorials.net/…
  • 对不起,我的意思是 UDF 而不是 HDF...错字...

标签: json apache-spark dataframe hive pyspark


【解决方案1】:

如果您调整 updateTime 函数以接收时间戳作为参数并返回新处理的时间戳,您可以创建一个 UDF 并直接在 DataFrame 的列上使用它:

from pyspark.sql.functions import *
from pyspark.sql.types import TimestampType

myUDF = udf(updateTime, TimestampType())
df = df.withColumn("timestamp", myUDF(col("timestamp"))

但是,在你的情况下,我认为它有点复杂:

from pyspark.sql.functions import *
from pyspark.sql.types import TimestampType

myUDF = udf(getClientTime, TimestampType())
client_timestamp = myUDF(col("data"))
server_timestamp = col("timestamp")
condition = server_timestamp.cast("float") - client_timestamp.cast("float") <= THRESHOLD_TIME    

newCol =  when(condition, client_timestamp).otherwise(server_timestamp) 
newDF = df.withColumn("new_timestamp", newCol)

使用第二种方法,函数getClientTimedata 列接收一个值,并返回该值的客户端时间戳。然后,您可以使用它来创建一个包含此信息的新列 (client_timestamp)。最后,您可以根据server_timestamp 列和新创建的client_timestamp 列的值,使用when 有条件地创建新列。

参考:

【讨论】:

  • 谢谢!该方法适用于一些小的变化。看起来我以前不明白 UDF 是如何工作的。编辑 myUDF 以返回 StringType() 并使用 df['column'] 而不是 col('column')
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-11
  • 2022-11-20
  • 1970-01-01
  • 1970-01-01
  • 2018-11-08
  • 2019-01-31
相关资源
最近更新 更多