我正在尝试使用Pyspark读取多个CSV文件,数据由Amazon Kinesis Firehose处理,因此它们以以下格式写入。
s3bucket/
YYYY/
mm/
dd/
hh/
files.gz
files.gz
files.gz
我实际上正在使用此代码通过正则表达式阅读一整天(例如2019年1月15日):
data = spark.read.format("s3selectJson").options(compression="GZIP", multiline=True) \
.load("s3://s3bucket/2019/01/15/*.gz".format(datetime_object.strftime("%Y/%m/%d")))
我的问题是,我如何才能知道我想要的日期来读取多天的数据?有自动的方法还是我应该为需要的日期制作一个正则表达式?
编辑:
我正在寻找的是下面文档中的DataFrameWriter.partitionBy(* cols)方法的反函数
http://spark.apache.org/docs/latest/api/python/pyspark.sql.html?highlight=regex#pyspark.sql.DataFrameWriter
答案 0 :(得分:1)
我担心,无法做到这一点。
如果您的数据结构如下(带有month =,year = ...),我们将其称为分区。
s3bucket/
year=YYYY/
month=mm/
day=dd/
hour=hh/
files.gz
files.gz
files.gz
您可以轻松加载数据(在某些情况下需要加载特定日期)
data = spark.read.format("s3selectJson").options(compression="GZIP", multiline=True) \
.load("s3://s3bucket/")
data_days = data.filter("day in (10, 20)")
使用分区,Spark仅加载您特定的日子,而不是整天。
答案 1 :(得分:0)
我没有找到它的函数,但是,这是一种解决方法:
datetime_object = datetime.strptime("2019-01-31", '%Y-%m-%d')
delta_days = 10
base_bucket = "s3://s3bucket/{}/*/*.gz"
bucket_names = []
for date in [datetime_object - timedelta(days=x) for x in range(0, delta_days)]:
bucket_names.append(base_bucket.format(date.strftime("%Y/%m/%d")))
幸运的是,.load()
函数使用一个列表作为源路径的参数,因此我根据所需的日期生成每个路径并将其提供给load函数。
data = spark.read.format("csv").options(compression="GZIP") \
.load(bucket_names)