【问题标题】:Pyspark extract multiple pattern from string columnPyspark 从字符串列中提取多个模式
【发布时间】:2022-06-10 18:36:26
【问题描述】:

我在一个非常大的数据框中有一个字符串列,我需要根据几种模式提取部分字符串。在这一步,一个匹配就足够了,我不想找到所有匹配的案例。这是对使用 regexp_extract 方法进行一个模式匹配的先前版本的改进请求。以下代码正在运行,但考虑到数据规模,效率不是很高:

sample_df = spark.createDataFrame(
  [       
      ("file pattern1"),
      ("file pattern2"),
      ("file pattern3")
  ],
  ['textCol'])
test = (sample_df
.withColumn("p1", F.regexp_extract(F.col('textCol'), pattern1, 1))
.withColumn("p2", F.regexp_extract(F.col('textCol'), pattern2, 1))
.withColumn("p3", F.regexp_extract(F.col('textCol'), pattern3, 1))
.withColumn("file", F.when(F.col("p1")!="", F.col("p1")).otherwise(F.when(F.col("p2")!="", F.col("p2")).otherwise(F.when(F.col("p3")!="", F.col("p3")).otherwise(""))))       
       )

另一种工作方式是 pandas_udf,我有这个功能,但出于性能考虑,我更喜欢将其保持在 spark 级别

@F.pandas_udf(returnType="string")
def get_file_dir(lines):
  res = []
  for l in lines:
    for r in reg_list:
      found=""
      m = re.search(r, l)
      if m:
        found=m.group(1)
        break
    res.append(found)
  return pd.Series(res)

我正在这里寻找任何代码优化建议,可能有助于减少我当前集群配置的运行时间。

【问题讨论】:

    标签: regex optimization pyspark bigdata


    【解决方案1】:

    您可以将所有模式组合在一起,用管道分隔|

    patterns = '|'.join([pattern1, pattern2, pattern3])
    test = sample_df.withColumn('file', F.regexp_extract('textCol', patterns, 0))
    

    之前:

    pattern1 = '(1$)'
    pattern2 = '(\d\d)'
    pattern3 = '(3$)'
    sample_df = spark.createDataFrame([("file pattern1",), ("file pattern2",), ("file pattern3",)], ['textCol'])
    
    test = (sample_df
        .withColumn("p1", F.regexp_extract(F.col('textCol'), pattern1, 1))
        .withColumn("p2", F.regexp_extract(F.col('textCol'), pattern2, 1))
        .withColumn("p3", F.regexp_extract(F.col('textCol'), pattern3, 1))
        .withColumn("file", F.when(F.col("p1")!="", F.col("p1")).otherwise(F.when(F.col("p2")!="", F.col("p2")).otherwise(F.when(F.col("p3")!="", F.col("p3")).otherwise(""))))       
    )
    test.show()
    # +-------------+---+---+---+----+
    # |      textCol| p1| p2| p3|file|
    # +-------------+---+---+---+----+
    # |file pattern1|  1|   |   |   1|
    # |file pattern2|   |   |   |    |
    # |file pattern3|   |   |  3|   3|
    # +-------------+---+---+---+----+
    

    之后:

    pattern1 = '(1$)'
    pattern2 = '(\d\d)'
    pattern3 = '(3$)'
    sample_df = spark.createDataFrame([("file pattern1",), ("file pattern2",), ("file pattern3",)], ['textCol'])
    
    patterns = '|'.join([pattern1, pattern2, pattern3])
    test = sample_df.withColumn('file', F.regexp_extract('textCol', patterns, 0))
    
    test.show()
    # +-------------+----+
    # |      textCol|file|
    # +-------------+----+
    # |file pattern1|   1|
    # |file pattern2|    |
    # |file pattern3|   3|
    # +-------------+----+
    

    如果您有超过 1 个小组,您将需要更改您的模式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-06
      • 2012-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多