我需要帮助来迭代使用DataFrame在Spark-Scala中编写的这段代码。我是Scala的新手,所以如果我的问题看似微不足道,我会道歉。
该函数非常简单:给定一个数据帧,如果存在模式匹配,该函数会转换列,否则选择所有字段。
/* Load sources */
val df = sqlContext.sql("select id_vehicle, id_size, id_country, id_time from " + working_database + carPark);
val df2 = df.select(
df.columns.map {
case id_vehicle @ "id_vehicle" => df(id_vehicle).cast("Int").as(id_vehicle)
case other => df(other)
}: _*
)
此功能与模式匹配完美配合!
现在我有一个问题:有没有办法“迭代”这个?在实践中,我需要一个给出dataframe
,Array[String]
列(column_1,column_2,...)和的另一个Array[String]
的函数输入(int,double,float,...),返回给我相同的dataframe
,并在正确的位置右转。
我需要帮助:))
答案 0 :(得分:1)
@Override
public void onAnimationEnd(Animation animation) {
view2.startAnimation(fade_out_animation);
if(textView4.isSelected()) {
textView4.setSelected(false);
textView4.setTextColor(getResources().getColor(R.color.light_gray));
} else {
textView4.setSelected(true);
textView4.setTextColor(getResources().getColor(R.color.yellow));
}
}
如果你有一个功能,你只需要多次应用同一个东西,折叠往往是你想要的。 上面的代码将两个数组拉在一起,将它们合并为一个。 然后,它会遍历此列表,每次都将您的函数应用于数据帧,然后将下一对应用于结果数据帧等。
根据你的编辑,我填写了上面的功能。我没有编译器,所以我不能100%确定它的正确性。写完之后我也开始质疑我原来的做法。以下是我认为更好的方法,但我将离开前一个参考。
//Your supplied code fits nicely into this function
def castOnce(df: DataFrame, colName: String, typeName: String): DataFrame = {
val colsCasted = df.columns.map{
case colName => df(colName).cast(typeName).as(colName)
case other => df(other)
}
df.select(colsCasted:_ *)
}
def castMany(df: DataFrame, colNames: Array[String], typeNames: Array[String]): DataFrame = {
assert(colNames.length == typeNames.length, "The lengths are different")
val colsWithTypes: Array[(String, String)] = colNames.zip(typeNames)
colsWithTypes.foldLeft(df)((cAndType, newDf) => castOnce(newDf, cAndType._1, cAndType._2))
}
上面的代码创建了一个列名称到所需类型的映射。 然后在数据框中的foreach列,它在Map中查找类型。 如果类型存在,我们将列转换为该新类型。如果Map中不存在该列,则我们会直接默认使用DataFrame中的列。
然后我们从DataFrame中选择这些列