在熊猫中,我有一个类似于
的功能indices = df.dateColumn.apply(holidays.index.searchsorted)
df['nextHolidays'] = holidays.index[indices]
df['previousHolidays'] = holidays.index[indices - 1]
计算距离最近的假日的距离并将其存储为新列。
searchsorted
http://pandas.pydata.org/pandas-docs/version/0.18.1/generated/pandas.Series.searchsorted.html对于大熊猫来说是一个很好的解决方案,因为它为我提供了下一个假期的索引,而没有高算法复杂度Parallelize pandas apply,例如这种方法比并行循环快得多。
如何在火花或蜂巢中实现这一目标?
答案 0 :(得分:1)
这可以使用聚合来完成,但是这种方法比pandas方法具有更高的复杂性。但是您可以使用UDF实现类似的性能。它不会像熊猫一样优雅,但是:
假设这个假期数据集:
holidays = ['2016-01-03', '2016-09-09', '2016-12-12', '2016-03-03']
index = spark.sparkContext.broadcast(sorted(holidays))
数据框中2016年日期的数据集:
from datetime import datetime, timedelta
dates_array = [(datetime(2016, 1, 1) + timedelta(i)).strftime('%Y-%m-%d') for i in range(366)]
from pyspark.sql import Row
df = spark.createDataFrame([Row(date=d) for d in dates_array])
UDF可以使用pandas searchsorted
,但需要在执行程序上安装pandas。 Insted你可以像这样使用plan python:
def nearest_holiday(date):
last_holiday = index.value[0]
for next_holiday in index.value:
if next_holiday >= date:
break
last_holiday = next_holiday
if last_holiday > date:
last_holiday = None
if next_holiday < date:
next_holiday = None
return (last_holiday, next_holiday)
from pyspark.sql.types import *
return_type = StructType([StructField('last_holiday', StringType()), StructField('next_holiday', StringType())])
from pyspark.sql.functions import udf
nearest_holiday_udf = udf(nearest_holiday, return_type)
可以与withColumn
一起使用:
df.withColumn('holiday', nearest_holiday_udf('date')).show(5, False)
+----------+-----------------------+
|date |holiday |
+----------+-----------------------+
|2016-01-01|[null,2016-01-03] |
|2016-01-02|[null,2016-01-03] |
|2016-01-03|[2016-01-03,2016-01-03]|
|2016-01-04|[2016-01-03,2016-03-03]|
|2016-01-05|[2016-01-03,2016-03-03]|
+----------+-----------------------+
only showing top 5 rows