我在数据框中有以下数据
col1 col2 col3 col4
1 desc1 v1 v3
2 desc2 v4 v2
1 desc1 v4 v2
2 desc2 v1 v3
我只需要col1,col2的每个独特组合的第一行,如下所示
Expected Output:
col1 col2 col3 col4
1 desc1 v1 v3
2 desc2 v4 v2
如何在pyspark(版本1.3.1)中实现此目的?
我尝试通过将数据帧转换为rdd然后应用map和reduceByKey函数然后将结果rdd转换回dataframe来实现相同目的。有没有其他方法可以使用数据帧函数执行上述操作?
答案 0 :(得分:2)
如果你想要一个任意行,你可以尝试使用first
或last
,但它远非漂亮,我会认真考虑升级Spark:
from pyspark.sql.functions import col, first
df = sc.parallelize([
(1, "desc1", "v1", "v3"), (2, "desc2", "v4", "v2"),
(1, "desc1", "v4", "v2"), (2, "desc2", "v1", "v3")
]).toDF(["col1", "col2", "col3", "col4"])
keys = ["col1", "col2"]
values = ["col3", "col4"]
agg_exprs = [first(c).alias(c) for c in keys + ["vs_"]]
select_exprs = keys + [
"vs_.col{0} AS {1}".format(i + 1, v) for (i, v) in enumerate(values)]
df_not_so_first = (df
.selectExpr("struct({}) AS vs_".format(",".join(values)), *keys)
.groupBy(*keys)
.agg(*agg_exprs)
.selectExpr(*select_exprs))
请注意,在此特定上下文中first
不会选择任何特定行,结果可能不具有确定性。此外,根据Spark版本,可以单独安排各个聚合。这意味着
df.groupBy("col1", "col2").agg(first("col3"), first("col4"))
不保证col3
和col4
将从同一行中选择。