如何在pyspark中合并数据框

时间:2018-10-30 20:40:58

标签: apache-spark pyspark

我一直在绞尽脑汁,我正在尝试执行以下操作。本质上,我有两个数据框,一个来自昨天,一个来自今天,这里今天只是一个增量(即仅新行)。我想将这两部分合并在一起,以便更新新行,并继续使用旧行。

sc = SparkContext.getOrCreate()

old = sc.parallelize([
    {"id": 1, "value": 10, "date": "yesterday"},
    {"id": 2, "value": 20, "date": "yesterday", "foo": "bar"},
    {"id": 3, "value": 30, "date": "yesterday"}
]).toDF()

new = sc.parallelize([
    {"id": 2, "value": 25, "date": "today"},
    {"id": 4, "value": 45, "date": "today"}
]).toDF()

expected = sc.parallelize([
    {"id": 1, "value": 10, "date": "yesterday"},
    {"id": 2, "value": 25, "date": "today"},
    {"id": 3, "value": 30, "date": "yesterday"},
    {"id": 4, "value": 45, "date": "today"},
]).toDF()

# something to merge old and new ...?

在纯python中,我只会使用:

old = {"a": 10, "b": 20, "c": 30 }
new = {"b": 25, "d": 45}
expected = {"a": 10, "b": 25, "c": 30, "d": 45 }
calculated = {**old, **new}

执行此操作的“正确”方法是什么?也许同时参加/推销?

编辑: 如前所述,这个问题是下面链接的重复。但是,该示例显示了针对非常具体的列名称的非常​​手动编码的查询。

我需要在大约5个数据帧中重用此代码,每个数据帧有20多个列,如果不需要,我不想针对列名对合并步骤进行硬编码;模式仍在变化。

在pyspark / spark中确实没有加入/合并功能吗?我有一个可以使用left_anti和union的解决方案,但是由于某种原因,它闻起来很不对劲。

1 个答案:

答案 0 :(得分:0)

我认为最简单的方法就是使用uniongroupbyfirst函数。

旧df:

+---+-----+---------+
| id|value|     date|
+---+-----+---------+
|  1|   10|yesterday|
|  2|   20|yesterday|
|  3|   30|yesterday|
+---+-----+---------+

新df:

+---+-----+---------+
| id|value|     date|
+---+-----+---------+
|  2|   25|    today|
|  4|   45|    today|
+---+-----+---------+

下面的代码合并两个数据框:

import pyspark.sql.functions as f

unionDF = old.union(new).sort("date")
unionDF.show()

联盟df:

+---+-----+---------+
| id|value|     date|
+---+-----+---------+
|  2|   25|    today|
|  4|   45|    today|
|  1|   10|yesterday|
|  2|   20|yesterday|
|  3|   30|yesterday|
+---+-----+---------+

最后一步,groupbyfirst函数:

firstCols = [f.first(col).alias(str(col)) for col in unionDF.columns[1:]]
finalDF = unionDF.groupby("id").agg(*firstCols).sort("id")

finalDF.show()

最终df:

+---+-----+---------+
| id|value|     date|
+---+-----+---------+
|  1|   10|yesterday|
|  2|   25|    today|
|  3|   30|yesterday|
|  4|   45|    today|
+---+-----+---------+