Spark - tải tệp CSV dưới dạng DataFrame?


140

Tôi muốn đọc một CSV trong tia lửa và chuyển đổi nó thành DataFrame và lưu trữ nó trong HDFS với df.registerTempTable("table_name")

Tôi đã thử:

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

Lỗi mà tôi nhận được:

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)

Lệnh đúng để tải tệp CSV dưới dạng DataFrame trong Apache Spark là gì?


kiểm tra liên kết
mrsrinivas

Câu trả lời:


178

spark-csv là một phần của chức năng Spark cốt lõi và không yêu cầu một thư viện riêng. Vì vậy, bạn chỉ có thể làm ví dụ

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

Trong scala, (điều này hoạt động cho bất kỳ định dạng nào - trong đề cập đến dấu phân cách "," cho csv, "\ t" cho tsv, v.v.)

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


163

Phân tích CSV và tải dưới dạng DataFrame / Dataset với Spark 2.x

Đầu tiên, khởi tạo SparkSessionđối tượng theo mặc định, nó sẽ có sẵn trong shell nhưspark

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

Sử dụng bất kỳ một trong những cách sau để tải CSV như DataFrame/DataSet

1. Thực hiện theo cách lập trình

 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")

Cập nhật: Thêm tất cả các tùy chọn từ đây trong trường hợp liên kết sẽ bị hỏng trong tương lai

  • đường dẫn : vị trí của tập tin. Tương tự như Spark có thể chấp nhận các biểu thức toàn cầu Hadoop tiêu chuẩn.
  • tiêu đề : khi được đặt thành true, dòng tệp đầu tiên sẽ được sử dụng để đặt tên cột và sẽ không được bao gồm trong dữ liệu. Tất cả các loại sẽ được giả định chuỗi. Giá trị mặc định là sai.
  • dấu phân cách : theo mặc định các cột được phân cách bằng cách sử dụng, nhưng dấu phân cách có thể được đặt thành bất kỳ ký tự nào
  • quote : theo mặc định ký tự trích dẫn là ", nhưng có thể được đặt thành bất kỳ ký tự nào. Dấu phân cách bên trong dấu ngoặc kép được bỏ qua
  • esc : theo mặc định, ký tự thoát là, nhưng có thể được đặt thành bất kỳ ký tự nào. Nhân vật trích dẫn bỏ qua được bỏ qua
  • ParserLib : theo mặc định, đó là " commons " có thể được đặt thành " univocity " để sử dụng thư viện đó để phân tích cú pháp CSV.
  • chế độ : xác định chế độ phân tích cú pháp. Theo mặc định, nó là PERMISSIVE. Các giá trị có thể là:
    • PERMISSIVE : cố gắng phân tích tất cả các dòng: null được chèn cho các mã thông báo bị thiếu và các mã thông báo bổ sung bị bỏ qua.
    • DROPMALFORMED : loại bỏ các dòng có ít hoặc nhiều mã thông báo hơn dự kiến ​​hoặc mã thông báo không khớp với lược đồ
    • FAILFAST : hủy bỏ với RuntimeException nếu gặp bất kỳ bộ ký tự dòng không đúng định dạng nào: mặc định là 'UTF-8' nhưng có thể được đặt thành các tên bộ ký tự hợp lệ khác
  • inferSchema : tự động xâm nhập các loại cột. Nó yêu cầu thêm một lần vượt qua dữ liệu và sai theo nhận xét mặc định: bỏ qua các dòng bắt đầu bằng ký tự này. Mặc định là "#". Vô hiệu hóa bình luận bằng cách đặt này thành null.
  • nullValue : chỉ định một chuỗi chỉ ra giá trị null, bất kỳ trường nào khớp với chuỗi này sẽ được đặt thành null trong DataFrame
  • dateFormat : chỉ định một chuỗi cho biết định dạng ngày sẽ sử dụng khi đọc ngày hoặc dấu thời gian. Các định dạng ngày tùy chỉnh tuân theo các định dạng tại java.text.SimpleDateFormat. Điều này áp dụng cho cả DateType và TimestampType. Theo mặc định, nó là null có nghĩa là cố gắng phân tích thời gian và ngày tháng bằng java.sql.Timestamp.valueOf () và java.sql.Date.valueOf ().

2. Bạn cũng có thể làm theo cách SQL này

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

Phụ thuộc :

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

Phiên bản Spark <2.0

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

Phụ thuộc:

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

làm phiên này yêu cầu tổ ong? Tôi đang nhận được lỗi tổ ong.
Puneet

2
Không cần. Chỉ spark-core_2.11spark-sql_2.11của 2.0.1phiên bản là tốt. Nếu có thể hãy thêm thông báo lỗi.
mrsrinivas

1
chúng ta có thể chuyển đổi một tập tin giới hạn đường ống thành một khung dữ liệu không?
Omkar

3
@OmkarPuttagunta: Vâng, tất nhiên rồi! hãy thử một vài thứ như thế này spark.read.format("csv").option("delimiter ", "|") ...
mrsrinivas

1
Tùy chọn khác programmatic waylà rời khỏi .format("csv")và thay thế .load(...bằng .csv(.... Các optionphương pháp thuộc về lớp DataFrameReader như được trả về bởi các readphương pháp, nơi loadcsvphương pháp trả về một dataframe vì vậy không thể có các tùy chọn gắn thẻ trên sau khi được gọi. Câu trả lời này khá kỹ lưỡng nhưng bạn nên liên kết với tài liệu để mọi người có thể thấy tất cả các tùy chọn CSV khác có sẵn spark.apache.org/docs/latest/api/scala/iêu *): org.apache.spark.sql.DataFrame
Davos

17

Nó có Hadoop là 2.6 và Spark là 1.6 và không có gói "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

Với Spark 2.0, sau đây là cách bạn có thể đọc 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
Có sự khác biệt giữa spark.read.csv(path)spark.read.format("csv").load(path)?
Eric

8

Trong Java 1.8 Đoạn mã này hoạt động hoàn hảo để đọc tệp 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();

Trong khi điều này có thể hữu ích cho một ai đó. Câu hỏi có thẻ Scala.
OneCricketeer

5

Có rất nhiều thách thức để phân tích tệp CSV, nó tiếp tục tăng nếu kích thước tệp lớn hơn, nếu không có tiếng Anh / esc / separator / các ký tự khác trong các giá trị cột, có thể gây ra lỗi phân tích cú pháp.

Phép thuật sau đó là trong các tùy chọn được sử dụng. Những cái đã làm việc cho tôi và hy vọng sẽ bao gồm hầu hết các trường hợp cạnh nằm trong mã dưới đây:

### 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)

Mong rằng sẽ giúp. Để tham khảo thêm: Sử dụng PySpark 2 để đọc CSV có mã nguồn HTML

Lưu ý: Mã ở trên là từ API Spark 2, trong đó API đọc tệp CSV đi kèm với các gói Spark có thể cài đặt được.

Lưu ý: PySpark là trình bao bọc Python cho Spark và chia sẻ cùng API với Scala / Java.



4

Ví dụ về Spark 2 của Penny là cách thực hiện trong spark2. Có thêm một mẹo: hãy tạo tiêu đề đó cho bạn bằng cách quét dữ liệu ban đầu, bằng cách đặt tùy chọn inferSchemathànhtrue

Ở đây, sau đó, giả sử đó sparklà một phiên tia lửa mà bạn đã thiết lập, là thao tác để tải trong tệp chỉ mục CSV của tất cả các hình ảnh Landsat mà máy chủ amazon trên 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")

Tin xấu là: điều này kích hoạt quét qua tệp; đối với một cái gì đó lớn như tệp CSV được nén 20 + MB này, có thể mất 30 giây trong một kết nối đường dài. Hãy ghi nhớ điều đó: tốt hơn hết là bạn nên mã hóa lược đồ một cách thủ công khi bạn đã đưa nó vào.

(đoạn mã Giấy phép Phần mềm Apache 2.0 được cấp phép để tránh mọi sự mơ hồ; điều gì đó tôi đã thực hiện dưới dạng thử nghiệm tích hợp / thử nghiệm tích hợp S3)


Tôi đã không thấy phương thức csv này hoặc chuyển bản đồ đến các tùy chọn. Đồng ý luôn luôn tốt hơn khi cung cấp lược đồ rõ ràng, inferSchema là tốt cho nhanh chóng bẩn (còn gọi là khoa học dữ liệu) nhưng khủng khiếp cho ETL.
Davos

2

Trong trường hợp bạn đang xây dựng một cái bình có scala 2.11 và Apache 2.0 trở lên.

Không cần phải tạo một sqlContexthoặc sparkContextđối tượng. Chỉ cần một SparkSessionđối tượng là đủ yêu cầu cho tất cả các nhu cầu.

Sau đây là mycode hoạt động tốt:

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()
  }
}

Trong trường hợp bạn đang chạy trong cluster chỉ cần thay đổi .master("local")để .master("yarn")khi xác định sparkBuilderđối tượng

Spark Doc bao gồm điều này: https://spark.apache.org/docs/2.2.0/sql-programming-guide.html


Điều này giống như câu trả lời hiện có
mrsrinivas

0

Thêm các phụ thuộc Spark sau vào tệp 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>

// Cấu hình Spark:

val spark = SparkSession.builder (). master ("local"). appName ("Ứng dụng mẫu"). getOrCreate ()

// Đọc tệp csv:

val df = spark.read.option ("tiêu đề", "true"). csv ("FILE_PATH")

// Hiển thị đầu ra

df.show ()


0

Để đọc từ đường dẫn tương đối trên hệ thống, hãy sử dụng phương thức System.getProperty để lấy thư mục hiện tại và sử dụng thêm để tải tệp bằng đường dẫn tương đối.

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)

tia lửa: 2.4.4 scala: 2.11.12


0

Với Spark 2.4+, nếu bạn muốn tải csv từ thư mục cục bộ, thì bạn có thể sử dụng 2 phiên và tải nó vào tổ ong. Phiên đầu tiên phải được tạo với cấu hình master () là "cục bộ [*]" và phiên thứ hai có "sợi" và kích hoạt Hive.

Một trong những dưới đây làm việc cho tôi.

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 ")

   }

Khi chạy với spark2-submit --master "yarn" --conf spark.ui.enabled=false testCSV.jarnó đã đi tốt và tạo ra bảng trong tổ ong.


-1

Định dạng tệp mặc định là Parquet với spark.read .. và tệp đọc csv rằng tại sao bạn lại nhận được ngoại lệ. Chỉ định định dạng csv với api bạn đang cố sử dụng


-1

Hãy thử điều này nếu sử dụng spark 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")

Lưu ý: - công việc này cho bất kỳ tập tin phân định. Chỉ cần sử dụng tùy chọn (del deliteriter,) để thay đổi giá trị.

Hy vọng điều này là hữu ích.


Điều này giống như câu trả lời hiện có
mrsrinivas

-1

Với Spark csv tích hợp, bạn có thể thực hiện dễ dàng với đối tượng SparkSession mới cho 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()

Có nhiều lựa chọn bạn có thể đặt.

  • header: liệu tệp của bạn có bao gồm dòng tiêu đề ở đầu không
  • inferSchema: cho dù bạn muốn suy luận lược đồ tự động hay không. Mặc định là true. Tôi luôn thích cung cấp lược đồ để đảm bảo các kiểu dữ liệu thích hợp.
  • mode: chế độ phân tích cú pháp, PERMISSIVE, DROPMALFORMED hoặc FAILFAST
  • delimiter: để chỉ định dấu phân cách, mặc định là dấu phẩy (',')
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.