web-dev-qa-db-fra.com

Comment puis-je ignorer un en-tête de fichiers CSV dans Spark?

Supposons que je donne trois chemins de fichiers à un contexte Spark à lire et que chaque fichier ait un schéma dans la première ligne. Comment pouvons-nous ignorer les lignes de schéma des en-têtes?

val rdd=sc.textFile("file1,file2,file3")

Maintenant, comment pouvons-nous ignorer les lignes d'en-tête de ce RDD?

57
Hafiz Mujadid

S'il n'y avait qu'une seule ligne d'en-tête dans le premier enregistrement, le moyen le plus efficace de le filtrer serait:

rdd.mapPartitionsWithIndex {
  (idx, iter) => if (idx == 0) iter.drop(1) else iter 
}

Cela n’aidera pas si, bien sûr, il y a beaucoup de fichiers contenant de nombreuses lignes d’en-tête. Vous pouvez syndiquer trois RDD que vous faites de cette façon, en effet.

Vous pouvez aussi simplement écrire une filter qui correspond uniquement à une ligne qui pourrait être un en-tête. C'est assez simple, mais moins efficace.

Équivalent Python:

from itertools import islice

rdd.mapPartitionsWithIndex(
    lambda idx, it: islice(it, 1, None) if idx == 0 else it 
)
59
Sean Owen
data = sc.textFile('path_to_data')
header = data.first() #extract header
data = data.filter(row => row != header)   #filter out header
86
Jimmy

Dans Spark 2.0, un lecteur CSV est intégré à Spark. Vous pouvez ainsi charger facilement un fichier CSV comme suit:

spark.read.option("header","true").csv("filePath")
50
Sandeep Purohit

À partir de Spark 2.0 à partir de maintenant, vous pouvez utiliser SparkSession pour que cela se fasse en une ligne:

val spark = SparkSession.builder.config(conf).getOrCreate()

et puis comme @SandeepPurohit a dit:

val dataFrame = spark.read.format("CSV").option("header","true").load(csvfilePath)

J'espère que cela a résolu votre question!

P.S: SparkSession est le nouveau point d’entrée introduit dans Spark 2.0 et se trouve sous package spark_sql

10
Shiv4nsh

Dans PySpark, vous pouvez utiliser un cadre de données et définir l'en-tête sur True:

df = spark.read.csv(dataPath, header=True)
5
hayj

Vous pouvez charger chaque fichier séparément, les filtrer avec file.zipWithIndex().filter(_._2 > 0), puis unir tous les RDD de fichiers.

Si le nombre de fichiers est trop important, le syndicat peut lancer une StackOverflowExeption.

5
pzecevic

Utilisez la méthode filter() dans PySpark en filtrant le nom de la première colonne pour supprimer l'en-tête:

# Read file (change format for other file formats)
contentRDD = sc.textfile(<filepath>)

# Filter out first column of the header
filterDD = contentRDD.filter(lambda l: not l.startswith(<first column name>)

# Check your result
for i in filterDD.take(5) : print (i)
3
kumara81205

C'est une option que vous passez à la commande read():

context = new org.Apache.spark.sql.SQLContext(sc)

var data = context.read.option("header","true").csv("<path>")
1
Sahan Jayasumana

Travailler en 2018 (Spark 2.3)

Python

df = spark.read.option("header","true").format("csv").schema(myManualSchema).load("maestraDestacados.csv")

Scala

val myDf = spark.read.option("header","true").format("csv").schema(myManualSchema).load("maestraDestacados.csv")

PD1: myManualSchema est un schéma prédéfini écrit par moi, vous pouvez ignorer cette partie du code

0
Antonio Cachuan

Vous pouvez également utiliser le package spark-csv (ou dans Spark 2.0, il est plus ou moins disponible nativement en tant que CSV). Notez que cela attend l'en-tête de chaque fichier (comme vous le souhaitez):

schema = StructType([
        StructField('lat',DoubleType(),True),
        StructField('lng',DoubleType(),True)])

df = sqlContext.read.format('com.databricks.spark.csv'). \
     options(header='true',
             delimiter="\t",
             treatEmptyValuesAsNulls=True,
             mode="DROPMALFORMED").load(input_file,schema=schema)
0
Adrian Bridgett