Esta respuesta amplía la respuesta aceptada, brinda más contexto y proporciona fragmentos de código que puede ejecutar en Spark Shell en su máquina.
Más contexto sobre la respuesta aceptada
La respuesta aceptada puede darle la impresión de que el código de muestra genera un solo mydata.csv
archivo y ese no es el caso. Demostremos:
val df = Seq("one", "two", "three").toDF("num")
df
.repartition(1)
.write.csv(sys.env("HOME")+ "/Documents/tmp/mydata.csv")
Esto es lo que se genera:
Documents/
tmp/
mydata.csv/
_SUCCESS
part-00000-b3700504-e58b-4552-880b-e7b52c60157e-c000.csv
NB mydata.csv
es una carpeta en la respuesta aceptada, ¡no es un archivo!
Cómo generar un solo archivo con un nombre específico
Podemos usar Spark-Daria para escribir un solo mydata.csv
archivo.
import com.github.mrpowers.spark.daria.sql.DariaWriters
DariaWriters.writeSingleFile(
df = df,
format = "csv",
sc = spark.sparkContext,
tmpFolder = sys.env("HOME") + "/Documents/better/staging",
filename = sys.env("HOME") + "/Documents/better/mydata.csv"
)
Esto generará el archivo de la siguiente manera:
Documents/
better/
mydata.csv
Rutas S3
Deberá pasar las rutas s3a DariaWriters.writeSingleFile
para usar este método en S3:
DariaWriters.writeSingleFile(
df = df,
format = "csv",
sc = spark.sparkContext,
tmpFolder = "s3a://bucket/data/src",
filename = "s3a://bucket/data/dest/my_cool_file.csv"
)
Ver aquí para obtener más información.
Evitar copyMerge
copyMerge se eliminó de Hadoop 3. La DariaWriters.writeSingleFile
implementación utiliza fs.rename
, como se describe aquí . Spark 3 todavía usaba Hadoop 2 , por lo que las implementaciones de copyMerge funcionarán en 2020. No estoy seguro de cuándo Spark se actualizará a Hadoop 3, pero es mejor evitar cualquier enfoque de copyMerge que haga que su código se rompa cuando Spark actualice Hadoop.
Código fuente
Busque el DariaWriters
objeto en el código fuente de spark-daria si desea inspeccionar la implementación.
Implementación de PySpark
Es más fácil escribir un solo archivo con PySpark porque puede convertir el DataFrame en un Pandas DataFrame que se escribe como un solo archivo por defecto.
from pathlib import Path
home = str(Path.home())
data = [
("jellyfish", "JALYF"),
("li", "L"),
("luisa", "LAS"),
(None, None)
]
df = spark.createDataFrame(data, ["word", "expected"])
df.toPandas().to_csv(home + "/Documents/tmp/mydata-from-pyspark.csv", sep=',', header=True, index=False)
Limitaciones
El DariaWriters.writeSingleFile
enfoque Scala y el df.toPandas()
enfoque Python solo funcionan para pequeños conjuntos de datos. Los conjuntos de datos enormes no se pueden escribir como archivos individuales. Escribir datos como un solo archivo no es óptimo desde la perspectiva del rendimiento porque los datos no se pueden escribir en paralelo.