7

Problem Durumu: Bir üzerinde (eşanlamlı listesinde ~ 40000 + Anahtar Değer çiftleri geniş koleksiyonundan) eşdeğeri sözlerle üst üste kelimelerin kelimeler değiştirmeniz gerekiyorarama Apache kıvılcım Java'nın kullanarak yerine

büyük veri kümesi (50000 satır).

Örnek:

Key | Value ------------------------------------ Allen | Apex Tool Group Armstrong | Columbus McKinnon DeWALT | StanleyBlack 

Üstü Eşanlamlı liste kullanılacak olan
Girdi

Allen jeevi pramod Allen Armstrong 
sandesh Armstrong jeevi 
harsha Nischay DeWALT 

Eşanlamlı listesi (anahtar değeri çifti) // Biz 40000 girişleri

Giriş ve Çıkış aşağıdaki biçimde gösterildiği gibi olmalıdır. Biz 3 ile çalıştık

Expected Output 

Apex Tool Group jeevi pramod Apex Tool Group Columbus McKinnon 
sandesh Columbus McKinnon jeevi 
harsha Nischay StanleyBlack 

hepsi kendi sınırlamaları `

UDF

public void test() { 
      List<Row> data = Arrays.asList(
      RowFactory.create(0, "Allen jeevi pramod Allen Armstrong"), 
      RowFactory.create(1, "sandesh Armstrong jeevi"), 
      RowFactory.create(2, "harsha Nischay DeWALT") 
     ); 

     StructType schema = new StructType(new StructField[] { 
      new StructField("label", DataTypes.IntegerType, false, Metadata.empty()), 
      new StructField("sentence", DataTypes.StringType, false, Metadata.empty()) 
     }); 
     Dataset<Row> sentenceDataFrame = spark.createDataFrame(data, schema); 

     List<Row> data2 = Arrays.asList(
      RowFactory.create("Allen", "Apex Tool Group"), 
      RowFactory.create("Armstrong","Columbus McKinnon"), 
      RowFactory.create("DeWALT","StanleyBlack") 
     ); 

     StructType schema2 = new StructType(new StructField[] { 
      new StructField("label2", DataTypes.StringType, false, Metadata.empty()), 
      new StructField("sentence2", DataTypes.StringType, false, Metadata.empty()) 
     }); 
     Dataset<Row> sentenceDataFrame2 = spark.createDataFrame(data2, schema2); 

     UDF2<String, String, Boolean> contains = new UDF2<String, String, Boolean>() 
     { 
      private static final long serialVersionUID = -5239951370238629896L; 

      @Override 
      public Boolean call(String t1, String t2) throws Exception { 
       return t1.contains(t2); 
      } 
     }; 
     spark.udf().register("contains", contains, DataTypes.BooleanType); 

     UDF3<String, String, String, String> replaceWithTerm = new UDF3<String, 
     String, String, String>() { 
      private static final long serialVersionUID = -2882956931420910207L; 

     @Override 
     public String call(String t1, String t2, String t3) throws Exception { 
      return t1.replaceAll(t2, t3); 
     } 
    }; 

    spark.udf().register("replaceWithTerm", replaceWithTerm, DataTypes.StringType); 

Dataset<Row> joined = sentenceDataFrame.join(sentenceDataFrame2, callUDF("contains", sentenceDataFrame.col("sentence"), sentenceDataFrame2.col("label2"))) 
             .withColumn("sentence_replaced", callUDF("replaceWithTerm", sentenceDataFrame.col("sentence"), sentenceDataFrame2.col("label2"), sentenceDataFrame2.col("sentence2"))) 
             .select(col("sentence_replaced")); 

joined.show(false); 
} 

kullanma

Yaklaşım 1

sahiptir yaklaşımlar

Giriş veri kümesinde birden çok eşanlamlı anahtar varsa, 1 numaralı yaklaşımla sorun, yukarıdaki örnek çıktısında gösterildiği gibi birçok satır oluşturuluyor. işlevi yerine ile ImmutableMap kullanma

Yaklaşım 2. tüm değiştirilmesi ile tek satır Beklenen: Burada anahtar tuttu ve ImmutableMap fonksiyonu içinde HashMap çifti değerleri, biz her şeyi değiştirmek için işlevini yerine denilen ama

: bir satırda birden fazla anahtar içeriyorsa o zaman burada
try { 

     JavaSparkContext sc = new JavaSparkContext(new SparkConf().setAppName("SparkJdbcDs").setMaster("local[*]")); 
     SQLContext sqlContext = new SQLContext(sc); 
     SparkSession spark = SparkSession.builder() 
       .appName("JavaTokenizerExample").getOrCreate(); 

     HashMap<String, String> options = new HashMap<String, String>(); 
     options.put("header", "true"); 
     Dataset<Row> dataFileContent = sqlContext.load("com.databricks.spark.csv", options); 
     dataFileContent=dataFileContent.withColumn("ManufacturerSource", regexp_replace(col("ManufacturerSource"),"[^a-zA-Z0-9\\s+]","")); 
     dataFileContent= dataFileContent.na().replace("ManufacturerSource",ImmutableMap.<String, String>builder() 
      .put("Allen", "Apex Tool Group"), 
      .put("Armstrong","Columbus McKinnon"), 
      .put("DeWALT","StanleyBlack") 
      //Here we have 40000 entries 
      .build() 

     ); 
      dataFileContent.show(10,false); 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

örnek kod ve çıkış olduğunu ... tek bir tuşa değiştirmeden tam satırı yok sayar Çıktı Stackoverflow istisna

public static void main(String[] args) { 
      JavaSparkContext sc = new JavaSparkContext(new SparkConf().setAppName("JoinFunctions").setMaster("local[*]")); 
      SQLContext sqlContext = new SQLContext(sc); 
      SparkSession spark = SparkSession.builder().appName("StringSimiliarityExample").getOrCreate(); 


      Dataset<Row> sourceFileContent = sqlContext.read() 
         .format("com.databricks.spark.csv") 
         .option("header", "true") 
         .load("source100.csv"); 
      sourceFileContent.show(false); 

     StructType schema = new StructType(new StructField[] { 
     new StructField("label", DataTypes.IntegerType, false, 
       Metadata.empty()), 
     new StructField("sentence", DataTypes.StringType, false, 
       Metadata.empty()) }); 
     Dataset<Row> sentenceDataFrame = spark.createDataFrame(data, schema); 
     UDF1 mode = new UDF1<String, String>() { 
      public String call(final String types) throws Exception { 
       return types.replaceAll("Allen", "Apex Tool Group") 
       .replaceAll("Armstrong","Columbus McKinnon") 
       .replaceAll("DeWALT","StanleyBlack") 
       //40000 more entries..... 
      } 
     }; 

     sqlContext.udf().register("mode", mode, DataTypes.StringType); 

     sentenceDataFrame.createOrReplaceTempView("people"); 
     Dataset<Row> newDF = sqlContext.sql("SELECT mode(sentence), label FROM people").withColumnRenamed("UDF(sentence)", "sentence"); 
     newDF.show(false); 
    } 

UDF içindeki tüm değiştirin kullanma 210

Yaklaşım 3

.

Burada, stackoverflow istisnası alıyoruz. Çünkü özyinelemeli işlev çağrısını andırıyor.

Lütfen bu sorunu çözmek için yardımcı olabilecek başka yenilikçi yaklaşımlar varsa bize bildirin.

cevap

0

Hiçbir zaman çalışmaz, çünkü her zaman alt dizgi eşleşmeleri sorununa sahip olursunuz. Örneğin: -> DE

  • ABCDE -

    • ABC> ABC metin "ABCDEF HIJ KLM" ile

    çıkışı nasıl olacak? Giriş ile aynı olmalıdır, ancak yaklaşımınız en iyi "DEDEF HIJ KLM" çıkışında olacak ve en kötüsünde çift değiştirme yapacak ve "DEF HIJ KLM" yi alacaksınız. Her iki durum da yanlıştır.

    Bu, belki regex kullanarak değiştirmelere sınırlar ekleyerek bunu geliştirebilirsiniz. Bununla birlikte, daha iyi bir yol, ilk olarak girişinizi doğru bir şekilde belirtmek, belirteç değiştirme (tam eşleşme olabilir) uygulamak ve daha sonra orijinal biçime yeniden belirsizleştirmektir. Bu, mekana göre bölünmek kadar basit olabilir, ancak belirteç sınırlarının ne olabileceğine dair doğru bir şekilde vermelisiniz. (Durur, tire, vb.).

  • +0

    Kaldırdığınız yönün bir kısmı doğrudur. Çift değiştirme gibi ama birkaç yaklaşım düşündük. 1. Tüm alt dizgi eşleşecek şekilde eşleşiyor 2. Tuşlara önce ve sonra boşluk ekleyin. Fakat bu, karşı karşıya olan temel sorun. Sorun, büyük veri kümeleri olduğumuz zamandır. – jeevitesh

    +0

    Eğer tokenize asla bir sorun olmayacaksa, sorun çözmeyecek –

    +0

    Tokenization, burada karşılaştığımız temel sorun, eşanlamlılar listesi (anahtar değeri az sayıda eşanlamlılar için kullanılması gereken eşanlamlılar listesi kayıtları sayısı çifti) 400 kayıt gibi 40000 gibi daha büyük set için çalıştığı gibi başarısız. – jeevitesh

    İlgili konular