我有大量的CSV文件,需要使用pyspark转换为镶木地板文件。 一个CSV到一个实木复合地板。
输入:csv文件:
000.csv
001.csv
002.csv
...
输出:qarquet文件:
000.parquet
001.parquet
002.parquet
...
我当前的解决方案是:
for each_csv in same_folder:
df = spark.read.csv(each_csv, header = True)
df.write.parquet(output_folder)
for循环很昂贵。有什么方法可以利用Spark进行批处理吗? 例如
spark.read.csv(same_folder / )。write.parquet(output_folder / )
根据QuickSilver的回答,这是我的PySpark版本:
spark = SparkSession.builder.master("local[*]").appName("csv_to_parquet").getOrCreate()
# Read csv files into a single data frame and add a column of input file names:
baseDf = spark.read.csv("input_folder/*.csv").withColumn("input_file_name", input_file_name())
# Convert file names into a list:
filePathInfo = baseDf.select("input_file_name").distinct().collect()
filePathInfo_array = list(map(lambda row: row.input_file_name, filePathInfo))
# Write to parquet:
map(lambda csvFileName: baseDf.filter(col("input_file_name").endsWith(csvFileName)).write.mode('overwrite').parquet(f'output_folder/{csvFileName}'), filePathInfo_array)
答案 0 :(得分:1)
您可以按照以下步骤操作,以避免在Spark中加载多个文件,
input_file_name
在文件名列表循环中,
scala中的Sudo工作代码
import java.nio.file.Paths
import org.apache.spark.sql.{Encoders, SaveMode, SparkSession}
import org.apache.spark.sql.functions._
object ReadWriteToRespCsv {
def main(args: Array[String]): Unit = {
val spark = SparkSession.builder.master("local[*]").getOrCreate;
val baseDf = spark.read.csv("src/main/resources/same_folder/*.csv")
//Add a column `input_file_name` which records source file name
.withColumn("input_file_name",input_file_name())
//Collect the file names into a List
val filePathInfo = baseDf.select("input_file_name").distinct()
.map(row=>Paths.get(row.getString(0)).getFileName.toString)(Encoders.STRING).collect()
//Iterate for file name list
filePathInfo.foreach(csvFileName => {
baseDf
//Filter dataframe by file name
.filter(col("input_file_name").endsWith(csvFileName) )
.write
.mode(SaveMode.Overwrite)
//Write to respective file
.parquet(s"src/main/resources/output_folder/${csvFileName}")
})
}
}
答案 1 :(得分:0)
您可以使用滚动模式选择文件,也可以提供文件列表。
如果文件夹/tmp/file1_csv/file1.csv
和/tmp/file2_csv/file2.csv
中有两个文件,则可以使用以下内容
spark.read.option("header", "true").csv("/tmp/file*_csv/*.csv")
或者,如果您有奇怪的路径,也可以使用csv
方法的重载版本。
val paths = "/dir1/,/dir2/,/dir3/"
val df = spark.read.option("header", "true").csv(paths.split(","): _*)