首页 > 解决方案 > Pyspark中具有不同列的两个数据框的交集

问题描述

我是数据科学的新手,我正在使用 Google Colab 进行一个简单的自我项目。我从something1.csv文件和something2.csv文件中获取数据。

df1 = spark.read.csv('something1.csv', header=True)
df2 = spark.read.csv('something2.csv', header=True)

something1.csv看起来的数据

#+----------+---------+----------+--------+-------+
#|   country| Latitude| Longitude|   col1 |  col2 |
#+----------+---------+----------+--------+-------+
#|   Andorra|   42.506|    1.5218|    2   |   1   |
#| Australia|   -31.81|    115.86|    1   |   6   |
#|   Austria|   41.597|    12.580|    4   |   9   |
#|   Belgium|   21.782|     1.286|    2   |   3   |
#|     India|   78.389|    12.972|    1   |   7   |
#|   Ireland|    9.281|     9.286|    9   |   8   |
#|       USA|   69.371|    21.819|    7   |   2   |
#+----------+---------+----------+--------+-------+

something2.csv看起来的数据

#+----------+---------+----------+--------+-------+
#|   country| Latitude| Longitude|   col1 |  col2 |
#+----------+---------+----------+--------+-------+
#| Australia|   -31.81|    115.86|    2   |   6   |
#|   Belgium|   21.782|     1.286|    1   |   6   |
#|     India|   78.389|    12.972|    3   |   5   |
#|       USA|   69.371|    21.819|    2   |   5   |
#+----------+---------+----------+--------+-------+

现在我想基于Longitudeand将 df2 与 df1 相交Latitude,并从 df1 中获取 df1 中存在的行以及 col1 和 col2。我的桌子应该看起来像

#+----------+---------+----------+--------+-------+
#|   country| Latitude| Longitude|   col1 |  col2 |
#+----------+---------+----------+--------+-------+
#| Australia|   -31.81|    115.86|    1   |   6   |
#|   Belgium|   21.782|     1.286|    2   |   3   |
#|     India|   78.389|    12.972|    1   |   7   |
#|       USA|   69.371|    21.819|    7   |   2   |
#+----------+---------+----------+--------+-------+

我尝试使用以下代码,但没有奏效。

new_df =  df1.intersect(df2) #using the intersection in pyspark which gave me null table

然后我也尝试了基于LatitudeLongitude

new_df = df2.select('Latitude','Longitude').intersect(df1.select('Latitude','Logitude')) #intersecting based on columns

我在 pyspark 中尝试了上述两种方法,但没有奏效。

标签: pythonapache-sparkpysparkapache-spark-sql

解决方案


Intersect仅获取两个数据框中共有的行。

  • 但在您的情况下,您需要col1,col2fromdf1和其他列df2,加入数据框(根据要求左/内)并仅从col1,col2df1 和 df2 的其他列中选择。

  • (或)如Mohammad Murtaza HashmiUse left_semijoin评论中所述

Example:

#using left semi join
df1.join(df2,['Latitude','Longitude'],'left_semi').show()

#using left join
df2.alias("t2").join(df1.alias("t1"),['Latitude','Longitude'],'left').select("t2.country","t2.Latitude","t2.Longitude","t1.col1","t1.col2").show()
#+---------+--------+---------+----+----+
#|  country|Latitude|Longitude|col1|col2|
#+---------+--------+---------+----+----+
#|Australia|  -31.81|   115.86|   1|   6|
#|  Belgium|  21.782|    1.286|   2|   3|
#|    India|  78.389|   12.972|   1|   7|
#|      USA|  69.371|   21.819|   7|   2|
#+---------+--------+---------+----+----+

Dynamic way:

#join columns
join_cols=[x for x in df1.columns if x.startswith("L")]

#selecting cols from t1
t1_cols=["t1."+x for x in df1.columns if x.startswith("col")]

#selecting cols from t2
t2_cols=["t2."+x for x in df2.columns if not x.startswith("col")]

df2.alias("t2").join(df1.alias("t1"),['Latitude','Longitude'],'inner').select(*t2_cols + t1_cols).show()

#+---------+--------+---------+----+----+
#|  country|Latitude|Longitude|col1|col2|
#+---------+--------+---------+----+----+
#|Australia|  -31.81|   115.86|   1|   6|
#|  Belgium|  21.782|    1.286|   2|   3|
#|    India|  78.389|   12.972|   1|   7|
#|      USA|  69.371|   21.819|   7|   2|
#+---------+--------+---------+----+----+

推荐阅读