我有两个文件/表格如下
File1:
101,10,20
102,30,40
103,50,60
和
File2:
101,10,20
104,70,80
103,50,55
在比较两个文件后,我需要创建新文件:
File3:
102,30,40,D
104,70,80,I
103,50,55,U
其中D
为“已删除”,I
为“已插入”且U
为“已更新”。
我尝试过使用RDD subtract
和SparkSQL,但在Spark 1.x中对子查询有限制。
答案 0 :(得分:0)
一个可能的想法是使用keyBy函数按您所需的密钥对两个RDD进行分组,然后应用不同的操作来计算 D , I , û。
请记住,join函数将与commun中的关键元素一起运行。所以在你的例子中(101,10,20)也将是加入的结果。您必须过滤此结果才能获得包含更改的键。
答案 1 :(得分:0)
我认为您正在寻找类似下面的内容。这里我有两个数据帧df1和df2。 df1是具有键列a1的主数据集,其与具有键列b1的辅助数据集df2进行比较。因此,如果键的字段a2,a3和b2,b3相同,则忽略这些记录。
是代码段。
from pyspark.sql.functions import udf
from pyspark.sql.types import *
from pyspark.sql import functions as F
input1 = [[101,10,20], [102,30,40], [103,50,60]]
input2 = [[101,10,20], [104,70,80], [103,50,55]]
df1 = sc.parallelize(input1).toDF(schema= StructType([StructField("a1", IntegerType(), False),StructField("a2", IntegerType(), False),StructField("a3", IntegerType(), False)]))
df2 = sc.parallelize(input2).toDF(schema=StructType([StructField("b1", IntegerType(), False),StructField("b2", IntegerType(), False),StructField("b3", IntegerType(), False)]))
joindf = df1.join(df2, [df1.a1 == df2.b1], 'outer').filter(((df1.a2 != df2.b2) | (df1.a3 != df2.b3)) | df1.a1.isNull() | df2.b1.isNull())
def check_row(a1, b1):
if not a1:
return 'D'
elif not b1:
return 'I'
else:
return 'U'
flagger = udf(check_row)
joindf.withColumn("flag", flagger(joindf.a1, joindf.b1)).select(F.when(joindf.a1.isNull(), joindf.b1).otherwise(joindf.a1).alias('a1'),F.when(joindf.a2.isNull(), joindf.b2).otherwise(joindf.a2).alias('a2'),F.when(joindf.a3.isNull(), joindf.b3).otherwise(joindf.a3).alias('a3'),'flag').show()
+---+---+---+----+
| a1| a2| a3|flag|
+---+---+---+----+
|103| 50| 60| U|
|102| 30| 40| I|
|104| 70| 80| D|
+---+---+---+----+
或者如果您更喜欢spark-sql,请使用以下代码段。
sqlContext.registerDataFrameAsTable(df1, 'df1')
sqlContext.registerDataFrameAsTable(df2, 'df2')
sqlContext.sql("""
SELECT
CASE WHEN a1 IS NULL THEN b1 ELSE a1 END as c1,
CASE WHEN a2 IS NULL THEN b2 ELSE a1 END as c2,
CASE WHEN a3 IS NULL THEN b3 ELSE a1 END as c3,
CASE
WHEN a1 IS NULL THEN 'I'
WHEN b1 is NULL THEN 'D'
ELSE 'U' END as flag
FROM df1 FULL OUTER JOIN df2 ON df1.a1 = df2.b1
WHERE (df1.a2 <> df2.b2 or df1.a3 <> df2.b3) or (df1.a1 is null) or (df2.b1 is null)
""").show()
+---+---+---+----+
| c1| c2| c3|flag|
+---+---+---+----+
|103|103|103| U|
|102|102|102| D|
|104| 70| 80| I|
+---+---+---+----+
答案 2 :(得分:0)
我认为我们可能需要稍微更改spark sql的代码以包含更新条件。
sqlContext.sql("""
SELECT
CASE when a1 IS NULL then b1 ELSE a1 END as c1,
CASE when a2 IS NULL then b2
when a1 = b1 then b2
else a2 END as c2,
CASE when a3 IS NULL then b3
when a1 = b1 then b3
else a3 END as c3,
CASE
when a1 IS NULL then 'I'
when b1 is NULL then 'D'
ELSE 'U' END as flag
FROM df1 FULL OUTER JOIN df2 ON df1.a1 = df2.b1
WHERE (df1.a2 <> df2.b2 or df1.a3 <> df2.b3) or (df1.a1 is null) or (df2.b1 is null)
""").show()