在pyspark中加入具有相同列名的数据框

Posted

技术标签:

【中文标题】在pyspark中加入具有相同列名的数据框【英文标题】:Joining Dataframes with same coumn name in pyspark 【发布时间】:2018-10-03 07:39:42 【问题描述】:

我有两个从两个 csv 文件中读取的数据框。

+---+----------+-----------------+
| ID|  NUMBER  |  RECHARGE_AMOUNT|
+---+----------+-----------------+
|  1|9090909092|               30|
|  2|9090909093|               30|
|  3|9090909090|               30|
|  4|9090909094|               30|
+---+----------+-----------------+

+---+----------+-----------------+
| ID|  NUMBER  |  RECHARGE_AMOUNT|
+---+----------+-----------------+
|  1|9090909092|               40|
|  2|9090909093|               50|
|  3|9090909090|               60|
|  4|9090909094|               70|
+---+----------+-----------------+

我正在尝试使用 NUMBER coumn 使用 pyspark 代码 dfFinal = dfFinal.join(df2, on=['NUMBER'], how='inner') 加入这两个数据,并按如下方式生成新的数据框。

+----------+---+-----------------+---+-----------------+
|  NUMBER  | ID|  RECHARGE_AMOUNT| ID|  RECHARGE_AMOUNT|
+----------+---+-----------------+---+-----------------+
|9090909092|  1|               30|  1|               40|
|9090909093|  2|               30|  2|               50|
|9090909090|  3|               30|  3|               60|
|9090909094|  4|               30|  4|               70|
+----------+---+-----------------+---+-----------------+

但我无法将此数据框写入文件,因为加入后的数据框有重复的列。我正在使用以下代码。 dfFinal.coalesce(1).write.format('com.databricks.spark.csv').save('/home/user/output',header = 'true') 加入spark后有什么办法可以避免重复列。下面给出的是我的 pyspark 代码。

from pyspark.sql import SparkSession
from pyspark.sql.functions import col
spark = SparkSession.builder.appName("test1").getOrCreate()
files = ["/home/user/test1.txt", "/home/user/test2.txt"]
dfFinal = spark.read.load(files[0],format="csv", sep=",", inferSchema="false", header="true", mode="DROPMALFORMED")
dfFinal.show()
for i in range(1,len(files)):
    df2 = spark.read.load(files[i],format="csv", sep=",", inferSchema="false", header="true", mode="DROPMALFORMED")
    df2.show()
    dfFinal = dfFinal.join(df2, on=['NUMBER'], how='inner')
dfFinal.show()
dfFinal.coalesce(1).write.format('com.databricks.spark.csv').save('/home/user/output',header = 'true')

我需要生成唯一的列名。即:如果我在 files 数组中给出了两个具有相同 coumn 的文件,它应该生成如下。

+----------+----+-------------------+-----+-------------------+
|  NUMBER  |IDx |  RECHARGE_AMOUNTx | IDy |  RECHARGE_AMOUNTy |
+----------+----+-------------------+-----+-------------------+
|9090909092|  1 |               30  |  1  |               40  |
|9090909093|  2 |               30  |  2  |               50  |
|9090909090|  3 |               30  |  3  |               60  |
|9090909094|  4 |               30  |  4  |               70  |
+----------+---+-----------------+---+------------------------+

在熊猫中,我可以使用suffixes 参数,如下所示dfFinal = dfFinal.merge(df2,left_on='NUMBER',right_on='NUMBER',how='inner',suffixes=('x', 'y'),sort=True),它将生成上述数据帧。有什么办法可以在 pyspark 上复制它。

【问题讨论】:

您能否尝试描述一下您希望如何查看将保存到文件中的输出数据框(没有重复的列)?例如您是否需要两个具有相同 ID 号的 ID 列?要将 RECHARGE_AMOUNT 重命名为 RECHARGE_AMOUNT_2 吗?等 您能否从第二个数据框中仅选择“数字”列然后进行连接?这样可以避免从第二个数据框中获取列。 我更新了问题。是的,我喜欢生成唯一的列名。例如 RECHARGE_AMOUNT_2.@Yaron 我也想要第一个数据帧中的 ID 和 RECHARGE_AMOUNT。@Constantine 【参考方案1】:

您可以从每个数据框中选择列并为其设置别名。 像这样。

dfFinal = dfFinal.join(df2, on=['NUMBER'], how='inner') \
                 .select('NUMBER',
                         dfFinal.ID.alias('ID_1'),
                         dfFinal.RECHARGE_AMOUNT.alias('RECHARGE_AMOUNT_1'),
                         df2.ID.alias('ID_2'),
                         df2.RECHARGE_AMOUNT.alias('RECHARGE_AMOUNT_2'))

【讨论】:

以上是关于在pyspark中加入具有相同列名的数据框的主要内容,如果未能解决你的问题,请参考以下文章

pyspark:删除所有行中具有相同值的列

在 PySpark 中加入多个列

将列表转换为数据框,然后在 pyspark 中加入不同的数据框

如何在 pyspark 中加入带有熊猫数据框的配置单元表?

在 PySpark 中加入 270 列

Pyspark在第二个数据框中加入多行数据框