스파크-CSV 파일을 DataFrame으로로드 하시겠습니까?


142

스파크에서 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)

Apache Spark에서 CSV 파일을 DataFrame으로로드하는 올바른 명령은 무엇입니까?


답변:


181

spark-csv는 핵심 Spark 기능의 일부이며 별도의 라이브러리가 필요하지 않습니다. 예를 들어

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

scala에서 (이것은 csv의 경우 ",", tsv의 경우 "\ t"등의 모든 형식 구분 기호에 적용됩니다)

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


164

CSV 구문 분석 및 Spark 2.x를 사용하여 DataFrame / DataSet으로로드

먼저 기본적으로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 표현식을 사용할 수 있습니다.
  • header : true로 설정하면 파일의 첫 번째 행이 열의 이름을 지정하는 데 사용되며 데이터에 포함되지 않습니다. 모든 유형은 문자열로 간주됩니다. 기본값은 false입니다.
  • 구분 기호 : 기본적으로 열은 구분 기호를 사용하지만 구분 기호는 모든 문자로 설정할 수 있습니다
  • quote : 기본적으로 따옴표 문자는 "이지만 모든 문자로 설정할 수 있습니다. 따옴표 안의 분리 문자는 무시됩니다.
  • escape : 기본적으로 이스케이프 문자는이지만 모든 문자로 설정할 수 있습니다. 이스케이프 된 따옴표는 무시됩니다
  • parserLib : 기본적으로 CSV 구문 분석에 해당 라이브러리를 사용 하기 위해 " univocity "로 설정할 수있는 " commons "입니다 .
  • mode : 파싱 모드를 결정합니다. 기본적으로 PERMISSIVE입니다. 가능한 값은 다음과 같습니다.
    • PERMISSIVE : 모든 행을 구문 분석하려고합니다. 누락 된 토큰에 대해 널이 삽입되고 추가 토큰이 무시됩니다.
    • DROPMALFORMED : 예상보다 적은 수 이상의 토큰이있는 행 또는 스키마와 일치하지 않는 토큰을 삭제합니다.
    • FAILFAST : 잘못된 행 문자 집합이 발견되면 RuntimeException과 함께 중단됩니다. 기본값은 'UTF-8'이지만 다른 유효한 문자 집합 이름으로 설정할 수 있습니다
  • inferSchema : 열 유형을 자동으로 유추합니다. 데이터를 한 번 더 전달해야하며 기본 주석에서는이 문자로 시작하는 줄을 건너 뜁니다. 기본값은 "#"입니다. 이 값을 null로 설정하여 주석을 비활성화하십시오.
  • nullValue : null 값을 나타내는 문자열을 지정합니다.이 문자열과 일치하는 모든 필드는 DataFrame에서 null로 설정됩니다.
  • 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,

이 세션에는 하이브가 필요합니까? 하이브 오류가 발생합니다.
Puneet

2
필요 없음. 만 spark-core_2.11spark-sql_2.112.0.1버전 괜찮습니다. 가능하면 오류 메시지를 추가하십시오.
mrsrinivas

1
파이프로 구분 된 파일을 데이터 프레임으로 변환 할 수 있습니까?
Omkar

3
@OmkarPuttagunta : 예, 물론입니다! 이와 같은 것을 시도해보십시오 spark.read.format("csv").option("delimiter ", "|") ...
mrsrinivas

1
다른 옵션 programmatic way은를 생략하고 .format("csv")로 대체 .load(...하는 것 .csv(...입니다. 이 option메소드는 메소드가 리턴 한대로 DataFrameReader 클래스에 속합니다 read. 여기서 loadand csv메소드는 데이터 프레임을 리턴하므로 옵션이 호출 된 후에 태그가 지정된 옵션을 가질 수 없습니다. 이 답변은 매우 철저하지만 사람들이 사용 가능한 다른 모든 CSV 옵션을 볼 수 있도록 설명서에 링크해야합니다. spark.apache.org/docs/latest/api/scala/… *) : org.apache.spark.sql.DataFrame
다 보스

17

Hadoop은 2.6이고 Spark는 1.6이며 "데이터 브릭"패키지가 없습니다.

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)있습니까?
Eric

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>

자바

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

이것은 누군가에게 유용 할 수 있지만. 질문에는 스칼라 태그가 있습니다.
OneCricketeer

5

CSV 파일을 구문 분석하는 데 많은 어려움이 있습니다. 파일 크기가 더 큰 경우, 열 값에 영어가 아닌 / 이스케이프 / 구분 기호 / 기타 문자가 있으면 구문 분석 오류가 발생할 수 있습니다.

마법은 사용되는 옵션에 있습니다. 나를 위해 일한 희망이 대부분의 가장 중요한 경우를 다루어야합니다. 아래 코드가 있습니다.

### 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를 사용하여 HTML 소스 코드가있는 CSV 읽기

참고 : 위의 코드는 Spark 2 API에서 가져온 것으로, CSV 파일 읽기 API에는 Spark 설치 가능 패키지가 기본 제공됩니다.

참고 : PySpark는 Spark 용 Python 래퍼이며 Scala / Java와 동일한 API를 공유합니다.


정말 감사합니다, 당신은 내 생명을 구했습니다 : D
Khubaib Raza

4

Penny 's Spark 2 예제는 spark2에서 수행하는 방법입니다. 한 가지 더 트릭이 있습니다. 옵션 inferSchema을 다음과 같이 설정하여 데이터를 초기 스캔하여 해당 헤더를 생성하십시오.true

여기에서 spark설정 한 스파크 세션이라고 가정하면 S3에서 호스트하는 모든 Landsat 이미지의 CSV 인덱스 파일에로드하는 작업입니다.

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

나쁜 소식은 파일을 통한 스캔을 유발한다는 것입니다. 이 20MB 이상의 압축 된 CSV 파일과 같은 큰 파일의 경우 장거리 연결시 30 초가 걸릴 수 있습니다. 명심하십시오 : 일단 스키마가 들어 오면 수동으로 코딩하는 것이 좋습니다.

(코드 스 니펫 Apache Software License 2.0은 모든 모호성을 피하기 위해 라이센스를 받았습니다. S3 통합의 데모 / 통합 테스트로 수행 한 작업)


이 csv 메소드를 보지 못하거나 옵션을지도에 전달하지 못했습니다. 명시 적 스키마를 제공하는 것이 항상 더 낫다는 데 동의 한 inferSchema는 데이터 과학과 같이 더럽고 ETL에는 끔찍합니다.
다 보스

2

scala 2.11 및 Apache 2.0 이상으로 jar을 빌드하는 경우.

sqlContext또는 sparkContext객체 를 만들 필요가 없습니다 . 그냥 SparkSession목적은 모든 요구에 대한 요구 사항을 충분하다.

다음은 잘 작동하는 mycode입니다.

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 파일에 다음 Spark 종속성을 추가하십시오.

<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 ( "local"). appName ( "Sample App"). getOrCreate ()

// CSV 파일을 읽습니다.

val df = spark.read.option ( "header", "true"). 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 () 구성을 사용하여 "local [*]"로 작성하고 두 번째 세션은 "yarn"및 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가 포함 된 Parquet이며 예외가 발생하는 이유입니다. 사용하려는 API로 CSV 형식을 지정하십시오.


-1

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

참고 :-이 구분 파일에 작동합니다. 옵션 (“구분 기호”)을 사용하여 값을 변경하십시오.

이것이 도움이 되길 바랍니다.


이것은 기존 답변과 동일합니다
mrsrinivas

-1

내장 된 Spark csv를 사용하면 Spark> 2.0에 대한 새로운 SparkSession 객체로 쉽게 수행 할 수 있습니다.

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: 구문 분석 모드, PERMISSIVE, DROPMALFORMED 또는 FAILFAST
  • delimiter: 구분 기호를 지정하려면 기본값은 쉼표 ( ',')입니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.