Spark >= 2.2
您可以跳过使用unix_timestamp
和cast
函数,而是直接使用to_date
或to_timestamp
函数:
from pyspark.sql.functions import to_date, to_timestamp
df_test.withColumn("date", to_date("date", "dd-MMM-yy")).show()
df_test.withColumn("date", to_timestamp("date", "dd-MMM-yy")).show()
然后应用下面展示的其他日期时间函数。
Spark < 2.2
在单个访问中无法派生多个顶级列。您可以使用结构体或集合类型,并像这样使用UDF:
from pyspark.sql.types import StringType, StructType, StructField
from pyspark.sql import Row
from pyspark.sql.functions import udf, col
schema = StructType([
StructField("day", StringType(), True),
StructField("month", StringType(), True),
StructField("year", StringType(), True)
])
def split_date_(s):
try:
d, m, y = s.split("-")
return d, m, y
except:
return None
split_date = udf(split_date_, schema)
transformed = df_test.withColumn("date", split_date(col("date")))
transformed.printSchema()
但在 PySpark 中,不仅语言冗长,而且代价高昂。
对于基于日期的转换,您可以简单地使用内置函数:
from pyspark.sql.functions import unix_timestamp, dayofmonth, year, date_format
transformed = (df_test
.withColumn("ts",
unix_timestamp(col("date"), "dd-MMM-yy").cast("timestamp"))
.withColumn("day", dayofmonth(col("ts")).cast("string"))
.withColumn("month", date_format(col("ts"), "MMM"))
.withColumn("year", year(col("ts")).cast("string"))
.drop("ts"))
同样地,您可以使用regexp_extract
来拆分日期字符串。
另请参见从Spark DataFrame中的单个列派生多个列
注意:
如果您使用未修补SPARK-11724版本,则在unix_timestamp(...)
之后,cast("timestamp")
之前需要进行更正。
unix_timestamp
,但这是唯一的重大变化。其余部分基本相同,SQL函数是推荐的方法。 - zero323