Hadoop / Spark读取许多CSV文件

时间:2016-10-26 15:35:08

标签: python csv hadoop apache-spark hdfs

我有很多结构化数据以非常有意义的方式存储,我希望以同样意义的完整和有效的方式处理它。

+- some-hdfs-path/
  +- level-1_var-01/
  |  +- level-2_var-001.csv
  |  +- ...
  |  +- level-2_var-nnn.csv
  +- level-1_var-02/
  |  +- level-2_other-001.csv
  |  +- ...
  |  +- level-2_other-mmm.csv
  +- ... /
  +- level-1_var-nn/
  |  +- ...

每个文件大约100MB,大约有1,000,000行。文件数(通常约为100)在每个目录中都有所不同,文件名也是如此。换句话说,我不知道有多少文件或它们被称为什么,但我确实需要他们的名字,显然他们的内容。

我无法处理从sc.textFile("/some-hdfs-path/level-1_var-01/*.csv")sc.wholeTextFiles("/some-hdfs-path/level-1_var-01")返回的RDD。

一般目标是实际获取level-1_var /目录中每个文件的第一行和最后一行。合并每个level-1_var的结果,然后返回并为每个级别写出全新的文件集-1_var / in some-other-hdfs-path / level-1-var /

我是Hadoop / Spark新手并使用RDD。我已经阅读了上述两个函数的documentation但我仍然对如何迭代我回来并进行处理的RDD感到困惑。

编辑:文件包含时间序列数据,因此不希望连接每个目录中的文件内容。我愿意将文件的内容作为附加列添加到一个巨型数据帧中,而不是作为行。

2 个答案:

答案 0 :(得分:0)

你可以使用spark 2.0的SparkSession对象,并给出csv'的目录

val df =spark.read.csv(pathOfDirectory)

上面的df将包含目录

中所有csv的数据

答案 1 :(得分:0)

使用此代码通过替换您的配置和属性来读取pySpark中的CSV。

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

def get_first_and_last(filename):
    #rdd variable holds the content of file(it's distributed)
    rdd = spark.read.csv(filename, header=True, mode="DROPMALFORMED").rdd

    #Here filename holds abs path. Feel free to substring as per your needs 
    return Row(filename, rdd.first, rdd.take(rdd.count()).last())


spark = SparkSession \
    .builder \
    .appName("Read CSVs") \
    .config("spark.some.config.option", "some-value") \
    .getOrCreate()

# This file list is not distributed one, It holds list of filenames only
filesList = spark.sparkContext\
    .wholeTextFiles("/some-hdfs-path/level-*_var-*/*.csv")\
    .map(lambda x: x[0])\  
    .collect()

#output array
records = filesList.map(get_first_and_last)

for record in records:
    print(record)

我已经尝试了scala中的等效代码,我可以根据需要查看结果。

修改:根据评论添加了另一种方法。

注意:使用sparkContext.wholeTextFiles()时首选小文件,因为每个文件都将完全加载到内存中。 documentation

records = spark.sparkContext\
    .wholeTextFiles("/some-hdfs-path/level-*_var-*/*.csv")\
    .map(lambda x : Row(x[0], x[1].split("\\n")[0], x[1].split("\\n")[-1]))\

for record in records.collect():
    print(record)

pySpark - SparkSession