web-dev-qa-db-fra.com

Obtenir le fichier CSV dans le cadre de données Spark

J'utilise python sur Spark et je voudrais obtenir un csv dans un cadre de données.

La documentation pour Spark SQL ne fournit étrangement pas d'explications sur CSV en tant que source.

J'ai trouvé Spark-CSV , mais j'ai des problèmes avec deux parties de la documentation:

  • "This package can be added to Spark using the --jars command line option. For example, to include it when starting the spark Shell: $ bin/spark-Shell --packages com.databricks:spark-csv_2.10:1.0.3" Ai-je vraiment besoin d'ajouter cet argument chaque fois que je lance pyspark ou spark-submit? Cela semble très inélégant. N'y a-t-il pas moyen de l'importer en python plutôt que de le retélécharger à chaque fois?

  • df = sqlContext.load(source="com.databricks.spark.csv", header="true", path = "cars.csv") Même si je fais ce qui précède, cela ne fonctionnera pas. Qu'est-ce que l'argument "source" représente dans cette ligne de code? Comment charger simplement un fichier local sur Linux, par exemple "/Spark_Hadoop/spark-1.3.1-bin-cdh4/cars.csv"?

16
Alexis Eggermont

Lisez le fichier csv dans un RDD, puis générez un RowRDD à partir du RDD d’origine.

Créez le schéma représenté par un StructType correspondant à la structure des lignes du RDD créé à l'étape 1.

Appliquez le schéma au RDD de lignes via la méthode createDataFrame fournie par SQLContext.

lines = sc.textFile("examples/src/main/resources/people.txt")
parts = lines.map(lambda l: l.split(","))
# Each line is converted to a Tuple.
people = parts.map(lambda p: (p[0], p[1].strip()))

# The schema is encoded in a string.
schemaString = "name age"

fields = [StructField(field_name, StringType(), True) for field_name in schemaString.split()]
schema = StructType(fields)

# Apply the schema to the RDD.
schemaPeople = spark.createDataFrame(people, schema)

source: GUIDE DE PROGRAMMATION SPARK

12
None
from pyspark.sql.types import StringType
from pyspark import SQLContext
sqlContext = SQLContext(sc)

Employee_rdd = sc.textFile("\..\Employee.csv")
               .map(lambda line: line.split(","))

Employee_df = Employee_rdd.toDF(['Employee_ID','Employee_name'])

Employee_df.show()
21

Avec les versions plus récentes de Spark (à partir de la version 1.4, je crois), cela est devenu beaucoup plus facile. L'expression sqlContext.read vous donne une DataFrameReader instance, avec une méthode .csv():

df = sqlContext.read.csv("/path/to/your.csv")

Notez que vous pouvez également indiquer que le fichier csv a un en-tête en ajoutant le mot clé argument header=True à l'appel .csv(). Une poignée d'autres options sont disponibles et décrites dans le lien ci-dessus.

20
ohruunuruus

Si la dépendance de paquet supplémentaire ne vous dérange pas, vous pouvez utiliser des pandas pour analyser le fichier CSV. Il gère très bien les virgules internes.

Les dépendances:

from pyspark import SparkContext
from pyspark.sql import SQLContext
import pandas as pd

Lisez tout le fichier en une fois dans un fichier de données Spark:

sc = SparkContext('local','example')  # if using locally
sql_sc = SQLContext(sc)

pandas_df = pd.read_csv('file.csv')  # assuming the file contains a header
# If no header:
# pandas_df = pd.read_csv('file.csv', names = ['column 1','column 2']) 
s_df = sql_sc.createDataFrame(pandas_df)

Ou, encore plus conscient des données, vous pouvez fractionner les données dans un Spark RDD puis DF:

chunk_100k = pd.read_csv('file.csv', chunksize=100000)

for chunky in chunk_100k:
    Spark_temp_rdd = sc.parallelize(chunky.values.tolist())
    try:
        Spark_full_rdd += Spark_temp_rdd
    except NameError:
        Spark_full_rdd = Spark_temp_rdd
    del Spark_temp_rdd

Spark_DF = Spark_full_rdd.toDF(['column 1','column 2'])
10
abby sobh

Après Spark 2.0, il est recommandé d’utiliser une session Spark:

from pyspark.sql import SparkSession
from pyspark.sql import Row

# Create a SparkSession
spark = SparkSession \
    .builder \
    .appName("basic example") \
    .config("spark.some.config.option", "some-value") \
    .getOrCreate()

def mapper(line):
    fields = line.split(',')
    return Row(ID=int(fields[0]), field1=str(fields[1].encode("utf-8")), field2=int(fields[2]), field3=int(fields[3]))

lines = spark.sparkContext.textFile("file.csv")
df = lines.map(mapper)

# Infer the schema, and register the DataFrame as a table.
schemaDf = spark.createDataFrame(df).cache()
schemaDf.createOrReplaceTempView("tablename")
6
Florent

pour Pyspark, en supposant que la première ligne du fichier csv contient un en-tête

spark = SparkSession.builder.appName('chosenName').getOrCreate()
df=spark.read.csv('fileNameWithPath', mode="DROPMALFORMED",inferSchema=True, header = True)
5
Grant Shannon

J'ai rencontré un problème similaire. La solution consiste à ajouter une variable d'environnement nommée "PYSPARK_SUBMIT_ARGS" et à définir sa valeur sur "--packages com.databricks: spark-csv_2.10: 1.4.0 pyspark-Shell". Cela fonctionne avec le shell interactif Python de Spark.

Assurez-vous de faire correspondre la version de spark-csv avec la version de Scala installée. Avec Scala 2.11, il s’agit de spark-csv_2.11 et avec Scala 2.10 ou 2.10.5, il s’agit de spark-csv_2.10.

Esperons que ça marche.

0
mahima

Basé sur la réponse de Aravind, mais beaucoup plus court, par exemple. :

lines = sc.textFile("/path/to/file").map(lambda x: x.split(","))
df = lines.toDF(["year", "month", "day", "count"])
0
JARS