比较两个 Dataframe 列并显示 df1 中可用的结果而不是 df2 [重复]

Posted

技术标签:

【中文标题】比较两个 Dataframe 列并显示 df1 中可用的结果而不是 df2 [重复]【英文标题】:Comparing two Dataframe columns and showing the result that is available in df1 and not in df2 [duplicate] 【发布时间】:2019-04-03 20:36:51 【问题描述】:

比较两个数据帧 df1(最近的数据)和 df2(以前的数据),它们是从同一张表中针对不同的时间戳派生的,并根据 df2 中不可用的列名 (id) 从 df1 中提取数据

我使用行号来提取最近和以前的数据,并将它们存储在 df1(recent data) 和 df2(previous data) 中。我尝试使用左连接,减法,但我不确定我是否在正确的轨道上。

df1=

ID|Timestamp           |RowNum|
+----------+-------------------+
|1|2019-04-03 14:45:...|     1|
|2|2019-04-03 14:45:...|     1|
|3|2019-04-03 14:45:...|     1|

df2 = 
ID|Timestamp           |RowNum|
+----------+-------------------+
|2|2019-04-03 13:45:...|     2|
|3|2019-04-03 13:45:...|     2|


%%spark
result2 = df1.join(df2.select(['id']), ['id'], how='left')
result2.show(10)

but didn't give the desired output
Required Output:

ID|Timestamp           |RowNum|
+----------+-------------------+
|1|2019-04-03 14:45:...|     1|

【问题讨论】:

【参考方案1】:

您可以使用left_anti 连接类型来做您想做的事:

result2 = df1.join(df2, ['id'], how='left_anti')

Spark 文档本身并没有很好地解释它,但您可以找到有关此连接类型 here 的更多信息。

【讨论】:

【参考方案2】:

有两种方法可以实现:

1 IS NOT IN - 从查找数据帧创建一个列表(df2_list)并在 isin() == False 中使用该列表

df1 = spark.createDataFrame([(1,"A") ,(2,"B",),(3,"C",),(4,"D")], ['id','item'])

df2 = spark.createDataFrame([(1,10) ,(2,20)], ['id','otherItem'])

df2_list = df2.select('id').rdd.map(lambda row : row[0]).collect()

from pyspark.sql.functions import col

df1.where(col('id').isin(df2_list) == False).show()

2 Left Anit Join - 将主表放在左侧。

df1.join(df2,  df1.id==df2.id, 'left_anti').show()

【讨论】:

感谢您的帮助。 Left_Semi 给出了我相信的表格中的共同值。不过不确定。我尝试谷歌搜索并发现。 @user11307842 - 我已经编辑了我的答案。你现在应该很好了。【参考方案3】:

试试这个。

scala> val df1 = Seq(("1","2019-04-03 14:45:00","1"),("2","2019-04-03 14:45:00","1"),("3","2019-04-03 14:45:00","1")).toDF("ID","Timestamp","RowNum")
df1: org.apache.spark.sql.DataFrame = [ID: string, Timestamp: string ... 1 more field]

scala> df1.show
+---+-------------------+------+
| ID|          Timestamp|RowNum|
+---+-------------------+------+
|  1|2019-04-03 14:45:00|     1|
|  2|2019-04-03 14:45:00|     1|
|  3|2019-04-03 14:45:00|     1|
+---+-------------------+------+

scala> val df2 = Seq(("2","2019-04-03 13:45:00","2"),("3","2019-04-03 13:45:00","2")).toDF("ID","Timestamp","RowNum")
df2: org.apache.spark.sql.DataFrame = [ID: string, Timestamp: string ... 1 more field]

scala> df2.show
+---+-------------------+------+
| ID|          Timestamp|RowNum|
+---+-------------------+------+
|  2|2019-04-03 13:45:00|     2|
|  3|2019-04-03 13:45:00|     2|
+---+-------------------+------+

scala> val idDiff = df1.select("ID").except(df2.select("ID"))
idDiff: org.apache.spark.sql.Dataset[org.apache.spark.sql.Row] = [ID: string]

scala> idDiff.show
+---+
| ID|
+---+
|  1|
+---+


scala> val outputDF = df1.join(idDiff, "ID")
outputDF: org.apache.spark.sql.DataFrame = [ID: string, Timestamp: string ... 1 more field]

scala> outputDF.show
+---+-------------------+------+
| ID|          Timestamp|RowNum|
+---+-------------------+------+
|  1|2019-04-03 14:45:00|     1|
+---+-------------------+------+

【讨论】:

以上是关于比较两个 Dataframe 列并显示 df1 中可用的结果而不是 df2 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

Pandas - 匹配来自两个数据帧的两列并在 df1 中创建新列

熊猫合并具有不同名称的列并避免重复[重复]

pandas中两个dataframe怎么比较

将Pandas DataFrame中的2列与.loc进行比较

pandas使用split函数将dataframe的特定字符串数据列裂变为两个新的数据列并生成新的dataframe

转换列并更新 DataFrame