pyspark rdd过滤器重复

时间:2020-09-04 06:04:09

标签: python apache-spark pyspark

我有这个rdd

rdd = sc.parallelize(['101,2020-09-04', 30.4, 0.0, 0.0], ['101,2020-09-04', 29.5, 45, 0.0], ['102,2020-09-04', 45.2, 48, 0.0])

我是python和pyspark的新手,我试图仅使用RDD方式解决此问题,我知道使用dataframe方式的解决方案,但仅需使用rdd方式即可。
我试图根据单元组/行中0.0的出现次数来过滤重复项。 表示第一个元组'101,2020-09-04'具有2乘以0.0,第二个元组具有0nly 1乘以0.0,所以我想在这里选择第二个元组。

我的预期输出是:

[['101,2020-09-04', 29.5, 45, 0.0], ['102,2020-09-04', 45.2, 48, 0.0]]

也不想为每个元组计数0.0,仅当id重复时才计数。

1 个答案:

答案 0 :(得分:0)

让我们通过这个工作。

# First we set up the problem
data = [['101,2020-09-04', 30.4, 0.0, 0.0], ['101,2020-09-04', 29.5, 45, 0.0], ['102,2020-09-04', 45.2, 48, 0.0]]
rdd = sc.parallelize(data)

# Break RDD rows into pairs: the common part to serve as our key, and the rest of the list
pair_rdd = rdd.map(lambda x: (x[0], x[1:]))
pair_rdd.collect()
#[('101,2020-09-04', [30.4, 0.0, 0.0]), ('101,2020-09-04', [29.5, 45, 0.0]), ('102,2020-09-04', [45.2, 48, 0.0])]

现在公共部分已分离,我们可以将其用于reduceByKey,但是首先我们需要一个用于比较列表值的函数。

# Comparing lists e.g. [1,0] > [0,1] -> True, because it compares elements 
# left to right. We reverse the lists in the function, so that the 
# zeros are on the left most side
# [0.0, 0.0, 30.4] < [0.0, 45, 29.5] -> True
def get_most_complete(record1, record2):
  if (record1[::-1] > record2[::-1]):
    return record1
  else:
    return record2

# Now we have our function and can reduceByKey
reduced_pair_rdd = pair_rdd.reduceByKey(lambda x,y: get_most_complete(x,y))

# Then we dismantle the pair into its original form
result = reduced_pair_rdd.map(lambda x: [x[0]] + x[1])
result.collect()
#[['101,2020-09-04', 29.5, 45, 0.0], ['102,2020-09-04', 45.2, 48, 0.0]]

这就是您想要的结果。