【问题标题】:How to import multiple csv files in a single load?如何在一次加载中导入多个 csv 文件?
【发布时间】:2016-10-05 00:43:03
【问题描述】:

假设我有一个定义的架构,用于在一个文件夹中加载 10 个 csv 文件。有没有办法使用 Spark SQL 自动加载表。我知道这可以通过为每个文件使用一个单独的数据框来执行[如下所示],但是它可以通过单个命令而不是指向一个文件来自动执行我可以指向一个文件夹吗?

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

【问题讨论】:

    标签: apache-spark apache-spark-sql spark-dataframe


    【解决方案1】:

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

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

    火花 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")
    

    注意事项:

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

    2. 使用spark 而不是sqlContext

    【讨论】:

    • 第一个解决方案似乎只加载文件夹中的第一个 csv。你知道如何加载它们吗?
    • @mdornfe1 - 它应该可以工作。当它不适合您时,我们需要了解案例的详细信息(spark 版本、使用的确切命令、csv 文件等)。如果它很短,请添加带有详细信息的评论,否则打开一个新问题。
    • 有没有办法从文件结构的不同深度加载文件?比如.../Downloads/first.csv.../Downloads/subfolder/second.csv?使用 .csv(".../Downloads/*/*.csv) 不会那样做。
    • @NotYanka 您可能想查看另一个答案——load 将接受路径列表作为字符串,并且每个路径都可能包含一个通配符。
    • @ohruunuruus 我尝试了另一个答案,但它不接受路径列表。还有其他建议吗?
    【解决方案2】:

    Ex1

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

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

    Ex2

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

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

    Ex3

    读取多个传递名称列表的 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: _*)
    

    Ex4

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

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

    Ex5

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

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

    【讨论】:

      【解决方案3】:

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

      -- One or more wildcard:
             .../Downloads20*/*.csv
      --  braces and brackets   
             .../Downloads201[1-5]/book.csv
             .../Downloads201{11,15,19,99}/book.csv
      

      【讨论】:

      【解决方案4】:

      读者文摘:(Spark 2.x)

      例如,如果您有 3 个目录保存 csv 文件:

      目录1,目录2,目录3

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

      路径 = "dir1/,dir2/,dir3/*"

      然后使用下面的函数并将这个paths变量传递给它

      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
      

      到那时运行:

      df = get_df_from_csv_paths(paths)
      

      您将在 df 中获得一个 spark 数据框,其中包含来自这 3 个目录中的所有 csv 的数据。

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

      完整版:

      如果您想提取多个目录中的多个 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 文件。

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

      这比联合好得多..

      【讨论】:

      • 这是我一直在寻找的答案,但答案比它需要的复杂得多。它可以从传递路径列表的简单示例中受益。从包含逗号分隔路径的字符串生成列表很方便,但有点超出了问题的范围。这个和其他东西(例如,功能丰富的花哨功能)导致我最初忽略了这个答案。
      • 这也是我一直在寻找的答案。这负责从多个存储桶/目录/格式等获取数据。
      • 同意@ohruunuruus - 很好的答案,但这里的人通常都足够流利地使用 Python,知道如何构建列表。
      【解决方案5】:

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

      【讨论】:

        【解决方案6】:
        val df = spark.read.option("header", "true").csv("C:spark\\sample_data\\*.csv)
        

        将考虑文件 tmp, tmp1, tmp2, ....

        【讨论】:

        • 有没有办法获取使用此命令读取的文件数?
        猜你喜欢
        • 1970-01-01
        • 2010-09-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-07
        • 2021-05-09
        • 2011-04-15
        相关资源
        最近更新 更多