问题描述
["Name","Address","TaxId","SS Number","Mobile Number","Gender","LastVisited"]
从这个 CSV,这些是我需要做的操作:
例如,在第一次迭代中,我将只选择列的一个子集:
[Col("Name"),Col("Address"),Col("Mobile Number"),Col("TaxId"),Lit("TaxIdentifier")]
我可以通过运行 for 循环、选择列并在最后执行 UnionAll 来完成所有这些。但是有没有更好的方法让 Spark 处理这个问题?
解决方法
您不需要循环但可以使用联合,如果您将数据框过滤到您想要的行,您可以使用 Union
- 在我使用的过滤器中 IsNotNull()
但你可以使用您喜欢的任何过滤器(如果您不确定过滤器语法,请向我们提供更多详细信息,我会提供帮助)。
var taxId = dataFrame.Filter(Functions.Col("TaxId").IsNotNull())
.WithColumn("UniqueId",Functions.Col("TaxId"));
var ssId = dataFrame.Filter(Functions.Col("ss").IsNotNull())
.WithColumn("UniqueId",Functions.Col("ss"));
var unionedDataFrame = taxId.Union(ssId);
unionedDataFrame.Show()
获得最终数据框后,您可以选择实际需要的列或删除不需要的列:
unionedDataFrame.Drop("TaxId").Show()
或
unionedDataFrame.Select("name,UniqueId").Show()
在 Spark 中,这与以下逻辑完全相同:
dataFrame.Filter(Functions.Col("TaxId").IsNotNull())
.WithColumn("UniqueId",Functions.Col("TaxId"))
.Union(
dataFrame.Filter(Functions.Col("ss").IsNotNull())
.WithColumn("UniqueId",Functions.Col("ss"))
).Show()
还要注意,当你调用一个方法时,你会得到一个新的 DataFrame,所以 dataFrame.Filter() 的结果是一个单独的 DataFrame 到 dataFrame
但需要注意的是,由于惰性求值,Spark在执行查询时创建计划。