合并两个PySpark DataFrame会产生意想不到的结果

时间:2017-10-27 17:36:11

标签: python apache-spark pyspark spark-dataframe

我有两个 PySpark DataFrames (不是pandas):

df1 =

    +----------+--------------+-----------+---------+
    |pk        |num_id        |num_pk     |qty_users|
    +----------+--------------+-----------+---------+
    |  63479840|      12556940|     298620|       13|
    |  63480030|      12557110|     298620|        9|
    |  63835520|      12627890|     299750|        8|

df2 =

    +----------+--------------+-----------+----------+
    |pk2       |num_id2       |num_pk2    |qty_users2|
    +----------+--------------+-----------+----------+
    |  63479800|      11156940|     298620|       10 |
    |  63480030|      12557110|     298620|        1 |
    |  63835520|      12627890|     299750|        2 |

我想加入两个DataFrame以获取一个DataFrame df

    +----------+--------------+-----------+---------+
    |pk        |num_id        |num_pk     |total    |
    +----------+--------------+-----------+---------+
    |  63479840|      12556940|     298620|       13|
    |  63479800|      11156940|     298620|       10|
    |  63480030|      12557110|     298620|       10|
    |  63835520|      12627890|     299750|       10|

合并的唯一条件是我想要为qty_users< pk, num_id, num_pk >中具有相同df1值的行总结df2的值。正如我在上面的例子中所示。

我该怎么做?

更新

这就是我所做的:

newdf = df1.join(df2,(df1.pk==df2.pk2) & (df1.num_pk==df2.num_pk2) & (df1.num_id==df2.num_id2),'outer')

newdf = newdf.withColumn('total', sum(newdf[col] for col in ["qty_users","qty_users2"]))

但它给了我9列而不是4列。如何解决这个问题?

2 个答案:

答案 0 :(得分:4)

外连接将返回两个表中的所有列。另外,我们必须在qty_users中填充空值,因为sum也将返回null。

最后,我们可以选择使用coalsece函数,

from pyspark.sql import functions as F

newdf = df1.join(df2,(df1.pk==df2.pk2) & (df1.num_pk==df2.num_pk2) & (df1.num_id==df2.num_id2),'outer').fillna(0,subset=["qty_users","qty_users2"])

newdf = newdf.withColumn('total', sum(newdf[col] for col in ["qty_users","qty_users2"]))

newdf.select(*[F.coalesce(c1,c2).alias(c1) for c1,c2 in zip(df1.columns,df2.columns)][:-1]+['total']).show()

+--------+--------+------+-----+
|      pk|  num_id|num_pk|total|
+--------+--------+------+-----+
|63479840|12556940|298620|   13|
|63480030|12557110|298620|   10|
|63835520|12627890|299750|   10|
|63479800|11156940|298620|   10|
+--------+--------+------+-----+

希望这有帮助。!

答案 1 :(得分:0)

这会输出你想要的吗?

df3 = pd.concat([df1, df2], as_index=False).groupby(['pk','num_id','num_pk'])['qty_users'].sum()

通过pd.concat([df1, df2], as_index=False)

合并您的2个数据帧

当所有其他列首先相同时,查找qty_users列的总和需要按这些列进行分组

groupby(['pk','num_id','num_pk'])

然后找到qty_users

的分组总和
['qty_users'].sum()