比较两个 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中的2列与.loc进行比较