web-dev-qa-db-ja.com

SparkおよびJava-空の値と引用符の処理)を使用したCSVファイルの書き込み

初期データはDataset <Row>にあり、パイプ区切りファイルに書き込もうとしています。空でないセルとnull以外の各値を引用符で囲みます。空またはnull値には引用符を含めないでください

result.coalesce(1).write()
            .option("delimiter", "|")
            .option("header", "true")
            .option("nullValue", "")
            .option("quoteAll", "false")
            .csv(Location);

予想される出力:

"London"||"UK"
"Delhi"|"India"
"Moscow"|"Russia"

現在の出力:

London||UK
Delhi|India
Moscow|Russia

「quoteAll」を「true」に変更すると、次の出力が得られます。

"London"|""|"UK"
"Delhi"|"India"
"Moscow"|"Russia"

Sparkのバージョンは2.3で、JavaバージョンはJava 8

6
Ram Grandhi

これは確かに効率的な回答ではありません。ArtemAlievからの回答に基づいてこれを変更しますが、それは少数の人々にとって有用であると考えたため、この回答を投稿します

import org.Apache.spark.sql.Dataset;
import org.Apache.spark.sql.Row;
import org.Apache.spark.sql.SparkSession;
import static org.Apache.spark.sql.functions.*;<br/>
import org.Apache.spark.sql.expressions.UserDefinedFunction;
import org.Apache.spark.sql.types.DataTypes;<br/>
public class Quotes {<br/>
    private static final String DELIMITER = "|";
    private static final String Location = "Give location here";

    public static void main(String[] args) {

        SparkSession sparkSession = SparkSession.builder() 
                .master("local") 
                .appName("Spark Session") 
                .enableHiveSupport()
                .getOrCreate();

        Dataset<Row> result = sparkSession.read()
                .option("header", "true")
                .option("delimiter",DELIMITER)
                .csv("Sample file to read"); //Give the details of file to read here

      UserDefinedFunction udfQuotesNonNull = udf(
        (String abc) -> (abc!=null? "\""+abc+"\"":abc),DataTypes.StringType
      );

      result = result.withColumn("ind_val", monotonically_increasing_id()); //inducing a new column to be used for join as there is no identity column in source dataset


      Dataset<Row> dataset1 = result.select((udfQuotesNonNull.apply(col("ind_val").cast("string")).alias("ind_val"))); //Dataset used for storing temporary results
      Dataset<Row> dataset = result.select((udfQuotesNonNull.apply(col("ind_val").cast("string")).alias("ind_val")));  //Dataset used for storing output

      String[] str = result.schema().fieldNames();
      dataset1.show();
      for(int j=0; j<str.length-1;j++)
      {
        dataset1 = result.select((udfQuotesNonNull.apply(col("ind_val").cast("string")).alias("ind_val")),(udfQuotesNonNull.apply(col(str[j]).cast("string")).alias("\""+str[j]+"\""))); 
        dataset=dataset.join(dataset1,"ind_val"); //Joining based on induced column
      }
      result = dataset.drop("ind_val");

      result.coalesce(1).write()
      .option("delimiter", DELIMITER)
      .option("header", "true")
      .option("quoteAll", "false")
      .option("nullValue", null)
      .option("quote", "\u0000") 
      .option("spark.sql.sources.writeJobUUID", false)
      .csv(Location);
    }
}
0
Ram Grandhi