Apache spark 我可以通过Spark读取文件的元数据吗
假设我们有两个文件,文件1在12:55创建,文件2在12:58创建。在读取这两个文件时,我想添加一个新的列创建时间。属于文件1的行在创建时间列中为12:55,属于文件2的行在创建时间列中为12:58Apache spark 我可以通过Spark读取文件的元数据吗,apache-spark,pyspark,apache-spark-sql,Apache Spark,Pyspark,Apache Spark Sql,假设我们有两个文件,文件1在12:55创建,文件2在12:58创建。在读取这两个文件时,我想添加一个新的列创建时间。属于文件1的行在创建时间列中为12:55,属于文件2的行在创建时间列中为12:58 new_data = spark.read.option("header", "true").csv("s3://bucket7838-1/input") 我使用上面的代码片段读取输入目录中的文件。以下是步骤 使用sparkcontext
new_data = spark.read.option("header", "true").csv("s3://bucket7838-1/input")
我使用上面的代码片段读取输入目录中的文件。以下是步骤
使用sparkcontext.wholeTextFiles/path/to/folder/containing/all/files
上面返回一个RDD,其中key是文件的路径,value是文件的内容
rdd.maplambda x:x[1]-这将为您提供一个仅包含文件内容的rdd
rdd.maplambda x:customeFunctionToProcessFileContentx
由于map函数是并行工作的,所以您所做的任何操作都会更快,而且不是顺序的——只要您的任务彼此不依赖,这是并行性的主要标准
不过,上面的方法适用于默认分区。所以,您可能无法获得与输出文件计数相等的输入文件计数,因为输出是分区数
您可以基于count或基于数据的任何其他唯一值重新划分RDD,因此最终输出文件计数等于输入计数。这种方法只具有并行性,但无法通过最佳分区数实现性能
使用sparkcontext.wholeTextFiles/path/to/folder/containing/all/files
上面返回一个RDD,其中key是文件的路径,value是文件的内容
rdd.maplambda x:x[1]-这将为您提供一个仅包含文件内容的rdd
rdd.maplambda x:customeFunctionToProcessFileContentx
由于map函数是并行工作的,所以您所做的任何操作都会更快,而且不是顺序的——只要您的任务彼此不依赖,这是并行性的主要标准
不过,上面的方法适用于默认分区。所以,您可能无法获得与输出文件计数相等的输入文件计数,因为输出是分区数
您可以基于count或基于数据的任何其他唯一值重新划分RDD,因此最终输出文件计数等于输入计数。这种方法只具有并行性,但不会通过最佳分区数实现性能使用输入文件名函数获取文件名,然后使用hdfs文件api获取文件时间戳,最后在文件名上连接两个数据帧
例如:
使用input_file_name函数获取文件名,然后使用hdfs file api获取文件时间戳,最后在文件名上连接两个数据帧
例如:
谢谢,我会研究这个解决方案。是否有任何可能使用数据帧的解决方案?在上面的解决方案中,我将获得文件的创建时间?编写一个UDF来获得您处理的每一行的创建时间。您可以一个接一个地处理文件,并将其传递给UDF,然后也可以进行spark加载。或者下面的代码用于从NAS导入os path='/home/user/datatest/'files=[]r=root,d=directories,f=os中r,d,f的文件。walkpath:f:if.txt文件中的文件:files.appendos.path.joinr,f文件中的文件:printf time.ctimeos.path.getmtimef spark.read.optionheader,true.csvs3://bucket7838-1/input这会读取目录中的所有文件,谁知道哪一行属于哪一个文件?你想让我逐个读取文件并使用boto3获取元数据?谢谢,我将研究此解决方案。是否有任何可能使用数据帧的解决方案?在上面的解决方案中,我将获得文件的创建时间?编写一个UDF来获得您处理的每一行的创建时间。您可以一个接一个地处理文件,并将其传递给UDF,然后也可以进行spark加载。或者下面的代码用于从NAS导入os path='/home/user/datatest/'files=[]r=root,d=directories,f=os中r,d,f的文件。walkpath:f:if.txt文件中的文件:files.appendos.path.joinr,f文件中的文件:printf time.ctimeos.path.getmtimef spark.read.optionheader,true.csvs3://bucket7838-1/input这会读取目录中的所有文件,谁会知道哪一行属于哪一个文件?你想让我一个接一个地读取文件并使用boto3获取元数据?谢谢你的精彩回答。所以必须有一个选项来升级两次:-@Shu,源代码是AWS S3。很好的回答:谢谢,有没有像creation\u date\u file这样的api提供文件的创建日期以及我们输入的文件名?好的。不管怎样,你的解决方案对我帮助很大。谢谢你的精彩回答。所以必须有一个选项来升级两次:-@Shu,源代码是AWS S3。很好的回答:谢谢,有没有像creation\u date\u file这样的api提供文件的创建日期以及我们输入的文件名?好的。不管怎样,你的解决方案对我帮助很大。
import os
import time
import pyspark
from pyspark.sql.functions import udf
from pyspark.sql.types import *
# reading all the files to create PairRDD
input_rdd = sc.wholeTextFiles("file:///home/user/datatest/*",2)
#convert RDD to DF
input_df=spark.createDataFrame(input_rdd)
input_df.show(truncate=False)
'''
+---------------------------------------+------------+
|_1 |_2 |
+---------------------------------------+------------+
|file:/home/user/datatest/test.txt |1,2,3 1,2,3|
|file:/home/user/datatest/test.txt1 |4,5,6 6,7,6|
+---------------------------------------+------------+
'''
input_df.select("_2").take(2)
#[Row(_2=u'1,2,3\n1,2,3\n'), Row(_2=u'4,5,6\n6,7,6\n')]
# function to get a creation time of a file
def time_convesion(filename):
return time.ctime(os.path.getmtime(filename.split(":")[1]))
#udf registration
time_convesion_udf = udf(time_convesion, StringType())
#udf apply over the DF
final_df = input_df.withColumn("created_time", time_convesion_udf(input_df['_1']))
final_df.show(2,truncate=False)
'''
+---------------------------------------+------------+------------------------+
|_1 |_2 |created_time |
+---------------------------------------+------------+------------------------+
|file:/home/user/datatest/test.txt |1,2,3 1,2,3|Sat Jul 11 18:31:03 2020|
|file:/home/user/datatest/test.txt1 |4,5,6 6,7,6|Sat Jul 11 18:32:43 2020|
+---------------------------------------+------------+------------------------+
'''
# proceed with the next steps for the implementation
from pyspark.sql.types import *
from pyspark.sql.functions import *
URI = sc._gateway.jvm.java.net.URI
Path = sc._gateway.jvm.org.apache.hadoop.fs.Path
FileSystem = sc._gateway.jvm.org.apache.hadoop.fs.FileSystem
Configuration = sc._gateway.jvm.org.apache.hadoop.conf.Configuration
fs = FileSystem.get(URI("hdfs://<namenode_address>:8020"), Configuration())
status = fs.listStatus(Path('<hdfs_directory>'))
filestatus_df=spark.createDataFrame([[str(i.getPath()),i.getModificationTime()/1000] for i in status],["filename","modified_time"]).\
withColumn("modified_time",to_timestamp(col("modified_time")))
input_df=spark.read.csv("<hdfs_directory>").\
withColumn("filename",input_file_name())
#join both dataframes on filename to get filetimestamp
df=input_df.join(filestatus_df,['filename'],"left")