我有一个输入数据帧(从一个hive表创建),包含超过100行。对于数据帧的每一行,我需要提取列值(大多数字符串)并将这些值传递给用户定义的函数。对于每一行,该函数使用这些输入值和其他中间数据帧(从hive表创建)来计算结果数据帧中的一组行和存储。 我如何实现这一目标 - 请帮忙。
我试过了:
var df1= hiveContext.sql("Select event_date,channelcode,st,tc,startsec,endsec from program_master")
var count1=df1.count()
df1 = df1.withColumn("INDEX", monotonically_increasing_id())
var i=1
while (i <= count1){
var ed = df1.filter(df1("INDEX") === s"""$i""").select(to_date(unix_timestamp(df1("ed"), "dd-MM-yy").cast(TimestampType)).cast(DateType)).first().getDate(0)
var cc = df1.filter(df1("INDEX") === s"""$i""").select(df1("cc")).first().getInt(0)
var ST = df1.filter(df1("INDEX") === s"""$i""").select(df1("ST")).first().getString(0)
var TC = df1.filter(df1("INDEX") === s"""$i""").select(df1("TC")).first().getString(0)
var ss = df1.filter(df1("INDEX") === s"""$i""").select(df1("ss")).first().getInt(0)
var es = df1.filter(df1("INDEX") === s"""$i""").select(df1("es")).first().getInt(0)
calculate_values(ed, cc, st, tc, ss, ss, sparkSession)
i=i+1
}
calculate_values def
def calculate_values(ed: Date,cc:Integer,ST:String,TC:String,ss:Integer,ss:Integer,sparkSession: SparkSession):Unit=
我尝试过的两个问题:因此没有输出 第3行:我希望它能给出1,2,3,...... 100等数字来迭代使用i - 但是它产生随机的非常大的数字。 第5行:它抛出java.util.NoSuchElementException:next on empty iterator
答案 0 :(得分:0)
monotonically_increasing_id()
会以不断增加的方式生成随机数,因此您无法依赖它来生成row_number()
函数的序列号。但是row_number()
在整个数据集上使用是昂贵的,因为它将收集一个执行器中的所有数据,除非您通过对数据进行分组来使用row_number()
。
monotonically_increasing_id()
会对您要订购/排序数据的情况有所帮助。
您似乎正在尝试使用 event_date , channelcode , st , tc逐行计算某些值, startsec 和 endsec 。
如果是逐行计算,那么我建议您使用udf
函数。因此,您可以将calculate_value
函数转换为udf
函数
import org.apache.spark.sql.functions._
def calculate_value = udf((ed: Date,cc:Int,ST:String,TC:String,ss:Int,es:Int) => //write your calculation part here)
您使用udf
作为
withColumn
函数
df1.withColumn("calculated", calculate(col("ed"), col("cc"), col("ST"), col("TC"), col("ss"), col("es"))
将使用计算值
创建新列但如果计算可以按列进行,我建议你再看inbuilt functions