如何在单个加载中导入多个csv文件?

Che*_*dur 38 apache-spark apache-spark-sql spark-dataframe

考虑我有一个已定义的架构,用于在文件夹中加载10个csv文件.有没有办法使用Spark SQL自动加载表.我知道这可以通过为每个文件[下面给出]使用单独的数据帧来执行,但是可以使用单个命令自动执行而不是指向文件我可以指向文件夹吗?

df = sqlContext.read
       .format("com.databricks.spark.csv")
       .option("header", "true")
       .load("../Downloads/2008.csv")
Run Code Online (Sandbox Code Playgroud)

Yar*_*ron 85

使用通配符,例如替换2008*:

df = sqlContext.read
       .format("com.databricks.spark.csv")
       .option("header", "true")
       .load("../Downloads/*.csv") // <-- note the star (*)
Run Code Online (Sandbox Code Playgroud)

Spark 2.0

// these lines are equivalent in Spark 2.0
spark.read.format("csv").option("header", "true").load("../Downloads/*.csv")
spark.read.option("header", "true").csv("../Downloads/*.csv")
Run Code Online (Sandbox Code Playgroud)

笔记:

  1. 替换format("com.databricks.spark.csv")为使用format("csv")csv替代.com.databricks.spark.csv格式已集成到2.0.

  2. 使用sparksqlContext

  • @NotYanka 您可能想查看其他答案——`load` 将接受一个路径列表作为字符串,并且每个路径都可能包含一个通配符。 (2认同)
  • @ohruunuruus 我尝试了另一个答案,但它不接受路径列表。还有其他建议吗? (2认同)

eiT*_*aVi 15

读者文摘:(Spark 2.x)

例如,如果您有3个目录,其中包含csv文件:

dir1,dir2,dir3

然后,您将路径定义为逗号分隔的路径列表的字符串,如下所示:

paths ="dir1/,dir2 /,dir3/*"

然后使用以下函数并将此路径变量传递给它

def get_df_from_csv_paths(paths):

        df = spark.read.format("csv").option("header", "false").\
            schema(custom_schema).\
            option('delimiter', '\t').\
            option('mode', 'DROPMALFORMED').\
            load(paths.split(','))
        return df
Run Code Online (Sandbox Code Playgroud)

然后运行:

df = get_df_from_csv_paths(paths)
Run Code Online (Sandbox Code Playgroud)

您将在df中获得一个包含来自这3个目录中找到的所有csv的数据的spark数据帧.

================================================== =========================

完整版本:

如果您想从多个目录中摄取多个CSV,您只需传递一个列表并使用通配符.

例如:

如果您的data_path如下所示:

's3:// bucket_name/subbucket_name/2016-09 - */184/*,
s3:// bucket_name/subbucket_name/2016-10 - */184/*,
s3:// bucket_name/subbucket_name/2016-11-*/184/*,
s3:// bucket_name/subbucket_name/2016-12 - */184/*,...'

您可以使用上面的函数立即摄取所有这些目录和子目录中的所有csv:

这将根据指定的通配符模式摄取s3 bucket_name/subbucket_name /中的所有目录.例如,第一个模式会查看

BUCKET_NAME/subbucket_name /

对于名称以.开头的所有目录

2016-09-

并为每个人只采取名为的目录

184

并在该子目录中查找所有csv文件.

这将针对逗号分隔列表中的每个模式执行.

这种工作方式比联盟更好..

  • 这是我一直在寻找的答案,但答案比它需要的要复杂得多。它可以从传递路径列表的简单示例中受益。从包含逗号分隔路径的字符串生成列表很方便,但有点超出了问题的范围。这个和其他东西(例如花哨的功能丰富的功能)使我最初忽略了这个答案。 (2认同)

小智 12

请注意,您可以使用其他技巧,例如:

-- One or more wildcard:
       .../Downloads20*/*.csv
--  braces and brackets   
       .../Downloads201[1-5]/book.csv
       .../Downloads201{11,15,19,99}/book.csv
Run Code Online (Sandbox Code Playgroud)


小智 8

示例1

读取单个CSV文件。提供完整的文件路径:

 val df = spark.read.option("header", "true").csv("C:spark\\sample_data\\tmp\\cars1.csv")
Run Code Online (Sandbox Code Playgroud)

示例2

读取多个通过名称传递的CSV文件:

val df=spark.read.option("header","true").csv("C:spark\\sample_data\\tmp\\cars1.csv", "C:spark\\sample_data\\tmp\\cars2.csv")
Run Code Online (Sandbox Code Playgroud)

范例3

通过名称列表读取多个CSV文件:

val paths = List("C:spark\\sample_data\\tmp\\cars1.csv", "C:spark\\sample_data\\tmp\\cars2.csv")
val df = spark.read.option("header", "true").csv(paths: _*)
Run Code Online (Sandbox Code Playgroud)

示例4

读取文件夹中的多个CSV文件而忽略其他文件:

val df = spark.read.option("header", "true").csv("C:spark\\sample_data\\tmp\\*.csv")
Run Code Online (Sandbox Code Playgroud)

示例5

从多个文件夹中读取多个CSV文件:

val folders = List("C:spark\\sample_data\\tmp", "C:spark\\sample_data\\tmp1")
val df = spark.read.option("header", "true").csv(folders: _*)
Run Code Online (Sandbox Code Playgroud)


Nee*_*nur 5

使用 Spark 2.0+,我们可以使用 .csv 文件从不同目录加载多个 CSV 文件 df = spark.read.csv(['directory_1','directory_2','directory_3'.....], header=True)。有关更多信息,请参阅此处的文档