如何在不使用collect()和for循环的情况下,将RPD python pyspark的另一列中的某个部分(IP地址)与其他IP地址进行比较

时间:2019-07-08 15:47:09

标签: python pyspark rdd

我有两个IP地址列表,它们位于单独的txt文件中。 我想通过比较两个数据集的前三个字节来进行比较。

例如:

a='123.43.54.231'
b='123.43.54.50'

由于前三个字节在a和b之间是相互的,所以我想提取完整的a(123.43.54.231)。

由于我处理的是RDD,因此考虑到它的大型数据集,应尽可能避免使用collect()。实际上,我编写了正确的代码来实现我想要的功能。但是,我所做的工作包含collect(),这使流程变得异常缓慢。

Python_3.7.3

from pyspark import SparkContext, SparkConf

  if __name__ == "__main__":
  conf = SparkConf().setAppName("Big_Data_Project").setMaster("local[*]")
  sc = SparkContext(conf = conf)

  Ip_1= sc.textFile("Ip_1.txt")

#Ip_1='''123.34.405.123 153.74.61.65 43.34.65.123 ...... '''
#Ip_2='''123.34.321.143 153.74.61.43 43.34.65.112 ...... '''

  Ip_2= sc.textFile("Ip_2.txt")

  y=[]
  def func():

      for i in Ip_1.collect():
          for x in Ip_2.collect():
              d=i[:i.rfind(".")]
              h=x[:x.rfind(".")]
              if d==h:
                  y.append(i)
              else:
                  pass
      return y
  Wanted_Ip=sc.parallelize(func())
  Wanted_Ip.repartition(1).saveAsTextFile("My Ip List")

正如我所解释的,我想获取Ip_1的 full ip_adress与Ip_2 RDD的前三个字节相匹配

153.74.61.65
43.34.65.123

我正在寻找一个不包含collect() 的解决方案。

1 个答案:

答案 0 :(得分:0)

您只需要生成一个要加入的密钥,然后执行加入:

common_ip.collect()                                                                                                                                                                                                                           

[('123.43.54', ('123.43.54.231', '123.43.54.50'))]

common_ip是一个rdd,其中每行是一个带有(:key,value)的对:

  • 键= 3位数ip
  • value =来自IP_1和IP_2的一对IP
common_ip.map(lambda x : x[1][0]).repartition(1).saveAsTextFile("My Ip List")

如果只需要IP_1的IP,则可以执行以下操作:

import neat