Іскра - завантажити файл CSV як DataFrame?


141

Я хотів би прочитати CSV в іскрі і перетворити його у DataFrame і зберігати його в HDFS df.registerTempTable("table_name")

Я намагався:

scala> val df = sqlContext.load("hdfs:///csv/file/dir/file.csv")

Помилка, яку я отримав:

java.lang.RuntimeException: hdfs:///csv/file/dir/file.csv is not a Parquet file. expected magic number at tail [80, 65, 82, 49] but found [49, 59, 54, 10]
    at parquet.hadoop.ParquetFileReader.readFooter(ParquetFileReader.java:418)
    at org.apache.spark.sql.parquet.ParquetRelation2$MetadataCache$$anonfun$refresh$6.apply(newParquet.scala:277)
    at org.apache.spark.sql.parquet.ParquetRelation2$MetadataCache$$anonfun$refresh$6.apply(newParquet.scala:276)
    at scala.collection.parallel.mutable.ParArray$Map.leaf(ParArray.scala:658)
    at scala.collection.parallel.Task$$anonfun$tryLeaf$1.apply$mcV$sp(Tasks.scala:54)
    at scala.collection.parallel.Task$$anonfun$tryLeaf$1.apply(Tasks.scala:53)
    at scala.collection.parallel.Task$$anonfun$tryLeaf$1.apply(Tasks.scala:53)
    at scala.collection.parallel.Task$class.tryLeaf(Tasks.scala:56)
    at scala.collection.parallel.mutable.ParArray$Map.tryLeaf(ParArray.scala:650)
    at scala.collection.parallel.AdaptiveWorkStealingTasks$WrappedTask$class.compute(Tasks.scala:165)
    at scala.collection.parallel.AdaptiveWorkStealingForkJoinTasks$WrappedTask.compute(Tasks.scala:514)
    at scala.concurrent.forkjoin.RecursiveAction.exec(RecursiveAction.java:160)
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

Яка правильна команда для завантаження CSV-файлу як DataFrame в Apache Spark?


Відповіді:


180

spark-csv є частиною основних функцій Spark і не потребує окремої бібліотеки. Так ви могли просто зробити, наприклад

df = spark.read.format("csv").option("header", "true").load("csvfile.csv")

У scala ((це працює для будь-якого згаданого відмітника формату "," для csv, "\ t" для tsv тощо)

val df = sqlContext.read.format("com.databricks.spark.csv") .option("delimiter", ",") .load("csvfile.csv")


163

Розбір CSV та завантаження як DataFrame / DataSet з Spark 2.x

Спочатку SparkSessionоб'єкт ініціалізує за замовчуванням, він буде доступний у оболонках якspark

val spark = org.apache.spark.sql.SparkSession.builder
        .master("local") # Change it as per your cluster
        .appName("Spark CSV Reader")
        .getOrCreate;

Для завантаження CSV використовуйте будь-який із наступних способів DataFrame/DataSet

1. Зробіть це програмно

 val df = spark.read
         .format("csv")
         .option("header", "true") //first line in file has headers
         .option("mode", "DROPMALFORMED")
         .load("hdfs:///csv/file/dir/file.csv")

Оновлення: Додавання всіх варіант тут в разі , якщо зв'язок буде порушено в майбутньому

  • шлях : розташування файлів. Аналогічно Spark може приймати стандартні вирази Hadoop globbing.
  • заголовок : коли встановлено значення true, перший рядок файлів буде використаний для імен стовпців і не буде включений у дані. Усі типи вважатимуться рядком. Значення за замовчуванням - помилкове.
  • роздільник : за замовчуванням стовпці розміщуються за допомогою, але роздільник може бути встановлений на будь-який символ
  • quota : за замовчуванням символ цитати є ", але його можна встановити будь-яким символом. Розмежувачі всередині лапок ігноруються
  • escape : за замовчуванням символ втечі є, але його можна встановити на будь-який символ. Символи цитати, що уникнули, ігноруються
  • parserLib : за замовчуванням це " commons " можна встановити на " univocity ", щоб використовувати цю бібліотеку для розбору CSV.
  • режим : визначає режим розбору. За замовчуванням це дозволено. Можливі значення:
    • PERMISSIVE : намагається проаналізувати всі рядки: нулі вставляються для відсутніх маркерів, а додаткові лексеми ігноруються.
    • DROPMALFORMED : скидає рядки, які мають менше або більше лексем, ніж очікувалося, або жетони, які не відповідають схемі
    • FAILFAST : скасовує програму RuntimeException, якщо зустрічається будь-яка неправильна лінійна діаграма: за замовчуванням на 'UTF-8', але її можна встановити на інші дійсні імена діаграм
  • inferSchema : автоматично виводить типи стовпців. Для цього потрібно один додатковий пропуск над даними та за замовчуванням є помилковим коментарем: пропустити лінії, починаючи з цього символу. За замовчуванням - "#". Відключіть коментарі, встановивши це значення "null".
  • nullValue : вказує рядок, який вказує на нульове значення, будь-які поля, що відповідають цій рядку, будуть встановлені як нулі в DataFrame
  • dateFormat : задає рядок, який вказує формат дати, який слід використовувати при читанні дат або часових позначок. Спеціальні формати дати дотримуйтесь форматів на java.text.SimpleDateFormat. Це стосується як DateType, так і TimestampType. За замовчуванням це null, що означає спробу розбору часу та дати за допомогою java.sql.Timestamp.valueOf () та java.sql.Date.valueOf ().

2. Ви також можете зробити цей спосіб SQL

 val df = spark.sql("SELECT * FROM csv.`hdfs:///csv/file/dir/file.csv`")

Залежності :

 "org.apache.spark" % "spark-core_2.11" % 2.0.0,
 "org.apache.spark" % "spark-sql_2.11" % 2.0.0,

Іскра-версія <2.0

val df = sqlContext.read
    .format("com.databricks.spark.csv")
    .option("header", "true") 
    .option("mode", "DROPMALFORMED")
    .load("csv/file/path"); 

Залежності:

"org.apache.spark" % "spark-sql_2.10" % 1.6.0,
"com.databricks" % "spark-csv_2.10" % 1.6.0,
"com.univocity" % "univocity-parsers" % LATEST,

чи потрібен цей сеанс вулика? Я отримую помилки у вуликах.
Пунеет

2
Нема потреби. Тільки spark-core_2.11і spark-sql_2.11від 2.0.1версії добре. Якщо можливо, додайте повідомлення про помилку.
mrsrinivas

1
чи можемо ми перетворити файл з обмеженим розміром труби у кадр даних?
Омкар

3
@OmkarPuttagunta: Так, поза курсом! спробуйте щось подібне spark.read.format("csv").option("delimiter ", "|") ...
mrsrinivas

1
Інший варіант для programmatic way, щоб залишити вимкнути .format("csv")і замінити .load(...з .csv(.... optionМетод відноситься до класу DataFrameReader, що повертається readметод, де loadі csvметоди повертають dataframe тому не може мати варіанти привласнюються після того як вони називаються. Ця відповідь досить ґрунтовна, але вам слід покластись на документацію, щоб люди могли бачити всі інші варіанти CSV, доступні spark.apache.org/docs/latest/api/scala/… *): org.apache.spark.sql.DataFrame
Давос

17

Це для кого Hadoop 2,6 і Spark 1,6 і без пакету "databricks".

import org.apache.spark.sql.types.{StructType,StructField,StringType,IntegerType};
import org.apache.spark.sql.Row;

val csv = sc.textFile("/path/to/file.csv")
val rows = csv.map(line => line.split(",").map(_.trim))
val header = rows.first
val data = rows.filter(_(0) != header(0))
val rdd = data.map(row => Row(row(0),row(1).toInt))

val schema = new StructType()
    .add(StructField("id", StringType, true))
    .add(StructField("val", IntegerType, true))

val df = sqlContext.createDataFrame(rdd, schema)

12

У програмі Spark 2.0 наведено далі, як можна читати CSV

val conf = new SparkConf().setMaster("local[2]").setAppName("my app")
val sc = new SparkContext(conf)
val sparkSession = SparkSession.builder
  .config(conf = conf)
  .appName("spark session example")
  .getOrCreate()

val path = "/Users/xxx/Downloads/usermsg.csv"
val base_df = sparkSession.read.option("header","true").
  csv(path)

5
Чи є різниця між spark.read.csv(path)і spark.read.format("csv").load(path)?
Ерік

8

У Java 1.8 Цей фрагмент коду прекрасно працює для читання файлів CSV

POM.xml

<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-core_2.11</artifactId>
    <version>2.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.spark/spark-sql_2.10 -->
<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-sql_2.10</artifactId>
    <version>2.0.0</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.scala-lang/scala-library -->
<dependency>
    <groupId>org.scala-lang</groupId>
    <artifactId>scala-library</artifactId>
    <version>2.11.8</version>
</dependency>
<dependency>
    <groupId>com.databricks</groupId>
    <artifactId>spark-csv_2.10</artifactId>
    <version>1.4.0</version>
</dependency>

Java

SparkConf conf = new SparkConf().setAppName("JavaWordCount").setMaster("local");
// create Spark Context
SparkContext context = new SparkContext(conf);
// create spark Session
SparkSession sparkSession = new SparkSession(context);

Dataset<Row> df = sparkSession.read().format("com.databricks.spark.csv").option("header", true).option("inferSchema", true).load("hdfs://localhost:9000/usr/local/hadoop_data/loan_100.csv");

        //("hdfs://localhost:9000/usr/local/hadoop_data/loan_100.csv");
System.out.println("========== Print Schema ============");
df.printSchema();
System.out.println("========== Print Data ==============");
df.show();
System.out.println("========== Print title ==============");
df.select("title").show();

Хоча це може бути корисним комусь. У питанні є тег Scala.
OneCricketeer

5

Проблема розбору CSV-файлів виникає дуже багато, він продовжує додавати, якщо розмір файлу більший, якщо в значеннях стовпців є не англійські / escape / separator / інші символи, які можуть спричинити помилки розбору.

Магія тоді в варіантах, які використовуються. Ті, які працювали на мене і, сподіваюся, повинні охопити більшість кращих випадків, наведені в коді нижче:

### Create a Spark Session
spark = SparkSession.builder.master("local").appName("Classify Urls").getOrCreate()

### Note the options that are used. You may have to tweak these in case of error
html_df = spark.read.csv(html_csv_file_path, 
                         header=True, 
                         multiLine=True, 
                         ignoreLeadingWhiteSpace=True, 
                         ignoreTrailingWhiteSpace=True, 
                         encoding="UTF-8",
                         sep=',',
                         quote='"', 
                         escape='"',
                         maxColumns=2,
                         inferSchema=True)

Сподіваюся, що це допомагає. Докладніше: Використання PySpark 2 для читання CSV, що має вихідний код HTML

Примітка. Код, наведений вище, від API Spark 2, де API для читання файлів CSV постачається в комплекті з вбудованими пакетами встановлення Spark.

Примітка: PySpark - обгортка Python для Spark і має той же API, що і Scala / Java.


Дякую так багато, Ти врятував мені життя: D
Хубайб Раза

4

Приклад Penny's Spark 2 - це спосіб зробити це в spark2. Є ще одна хитрість: створити для вас цей заголовок, виконавши первинну перевірку даних, встановивши параметр inferSchemaнаtrue

Тоді, припускаючи, що sparkце іскровий сеанс, який ви встановили, - це операція з завантаження в індексний файл CSV всіх зображень Landsat, які розміщують amazon на S3.

  /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to You under the Apache License, Version 2.0
   * (the "License"); you may not use this file except in compliance with
   * the License.  You may obtain a copy of the License at
   *
   *    http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */

val csvdata = spark.read.options(Map(
    "header" -> "true",
    "ignoreLeadingWhiteSpace" -> "true",
    "ignoreTrailingWhiteSpace" -> "true",
    "timestampFormat" -> "yyyy-MM-dd HH:mm:ss.SSSZZZ",
    "inferSchema" -> "true",
    "mode" -> "FAILFAST"))
  .csv("s3a://landsat-pds/scene_list.gz")

Погана новина: це запускає сканування через файл; для чогось такого, як цей CSV-файл із 20 + Мб, що може тривати 30 хвилин за тривалого зв'язку. Майте це на увазі: вам краще вручну кодувати схему, як тільки ви отримаєте її.

(фрагмент коду Apache Software License 2.0 ліцензується, щоб уникнути будь-якої неоднозначності; те, що я зробив як демо / інтеграційний тест інтеграції S3)


Я не бачив цього методу csv або передав карту опціям. Завжди краще погоджуватись із наданням явної схеми, inferSchema чудово підходить для швидкого забруднення (він же наука даних), але жахливий для ETL.
Давос

2

Якщо ви будуєте баночку зі шкалою 2.11 та Apache 2.0 або новішою.

Не потрібно створювати sqlContextабо sparkContextоб’єкт. Просто SparkSessionоб'єкта достатньо для всіх потреб.

Далі йде мій код, який працює чудово:

import org.apache.spark.sql.{DataFrame, Row, SQLContext, SparkSession}
import org.apache.log4j.{Level, LogManager, Logger}

object driver {

  def main(args: Array[String]) {

    val log = LogManager.getRootLogger

    log.info("**********JAR EXECUTION STARTED**********")

    val spark = SparkSession.builder().master("local").appName("ValidationFrameWork").getOrCreate()
    val df = spark.read.format("csv")
      .option("header", "true")
      .option("delimiter","|")
      .option("inferSchema","true")
      .load("d:/small_projects/spark/test.pos")
    df.show()
  }
}

У випадку, якщо ви працюєте в кластері, просто перейдіть .master("local")до .master("yarn")визначення sparkBuilderоб'єкта

Програма Spark Doc охоплює це: https://spark.apache.org/docs/2.2.0/sql-programming-guide.html


Це те саме, що і відповіді
mrsrinivas

0

Додайте наступні іскрові залежності у файл POM:

<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-core_2.11</artifactId>
    <version>2.2.0</version>
</dependency>
<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-sql_2.11</artifactId>
    <version>2.2.0</version>
</dependency>

// Конфігурація іскри:

val spark = SparkSession.builder (). master ("локальний"). appName ("Приклад програми"). getOrCreate ()

// Прочитати файл csv:

val df = spark.read.option ("заголовок", "правда"). csv ("FILE_PATH")

// Відображення виводу

df.show ()


0

Для читання з відносного шляху в системі використовуйте метод System.getProperty для отримання поточного каталогу та подальшого використання для завантаження файлу за допомогою відносного шляху.

scala> val path = System.getProperty("user.dir").concat("/../2015-summary.csv")
scala> val csvDf = spark.read.option("inferSchema","true").option("header", "true").csv(path)
scala> csvDf.take(3)

іскра: 2.4.4 шкала: 2.11.12


0

За допомогою Spark 2.4+, якщо ви хочете завантажити csv з локального каталогу, ви можете використовувати 2 сеанси і завантажити його у вулик. Перший сеанс повинен бути створений з конфігурацією master () як "локальний [*]", а другий сеанс із "пряжею" та увімкненим Hive.

Нижній працював на мене.

import org.apache.log4j.{Level, Logger}
import org.apache.spark._
import org.apache.spark.rdd._
import org.apache.spark.sql._

object testCSV { 

  def main(args: Array[String]) {
    Logger.getLogger("org").setLevel(Level.ERROR)
    val spark_local = SparkSession.builder().appName("CSV local files reader").master("local[*]").getOrCreate()

    import spark_local.implicits._
    spark_local.sql("SET").show(100,false)
    val local_path="/tmp/data/spend_diversity.csv"  // Local file
    val df_local = spark_local.read.format("csv").option("inferSchema","true").load("file://"+local_path) // "file://" is mandatory
    df_local.show(false)

    val spark = SparkSession.builder().appName("CSV HDFS").config("spark.sql.warehouse.dir", "/apps/hive/warehouse").enableHiveSupport().getOrCreate()

    import spark.implicits._
    spark.sql("SET").show(100,false)
    val df = df_local
    df.createOrReplaceTempView("lcsv")
    spark.sql(" drop table if exists work.local_csv ")
    spark.sql(" create table work.local_csv as select * from lcsv ")

   }

Коли побігли з spark2-submit --master "yarn" --conf spark.ui.enabled=false testCSV.jarнею, пішли чудово і створили стіл у вулику.


-1

Формат файлу за замовчуванням - Паркет з spark.read .. і читання файлів csv, тому ви отримуєте виняток. Вкажіть формат csv з api, який ви намагаєтесь використовувати


-1

Спробуйте це, якщо використовуєте іскру 2.0+

For non-hdfs file:
df = spark.read.csv("file:///csvfile.csv")


For hdfs file:
df = spark.read.csv("hdfs:///csvfile.csv")

For hdfs file (with different delimiter than comma:
df = spark.read.option("delimiter","|")csv("hdfs:///csvfile.csv")

Примітка: - це робота для будь-якого файлу з розмежуванням. Просто використовуйте параметр ("роздільник",), щоб змінити значення.

Сподіваюся, що це корисно.


Це те саме, що і відповіді
mrsrinivas

-1

За допомогою вбудованого Spark csv ви можете легко зробити це за допомогою нового об'єкта SparkSession для Spark> 2.0.

val df = spark.
        read.
        option("inferSchema", "false").
        option("header","true").
        option("mode","DROPMALFORMED").
        option("delimiter", ";").
        schema(dataSchema).
        csv("/csv/file/dir/file.csv")
df.show()
df.printSchema()

Ви можете встановити різні варіанти.

  • header: чи містить у вашому файлі рядок заголовка вгорі
  • inferSchema: ви хочете зробити схему автоматично або ні. За замовчуванням є true. Я завжди вважаю за краще надати схему для забезпечення належних типів даних.
  • mode: режим синтаксичного розбору, ДОКЛАДНИЙ, ДРОПМАЛЬФОРМОВАНИЙ або НЕПРИМЕЧНИЙ
  • delimiter: щоб вказати роздільник, за замовчуванням - кома (',')
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.