我正在尝试使用Pyspark生成Parquet文件。我发现在生成的Parquet文件的元数据中,未设置TimestampType和DecimalType列的统计信息(IntegerType和DateType列很好)。
使用PyArrow读取镶木地板文件时,我需要统计信息(最小值和最大值)来过滤行组。
我正在使用pyspark 2.4.0生成镶木地板文件,并使用pyarrow 0.12.1读取它们:
import datetime
from decimal import Decimal
from pyarrow import parquet
from pyspark import SparkConf, SparkContext, SQLContext
from pyspark.sql.types import (
StructField,
StructType,
IntegerType,
DateType,
TimestampType,
DecimalType,
)
data = [
(100, datetime.date(2019, 3, 1), datetime.datetime(2019, 3, 1, 1), Decimal('100.0')),
(200, datetime.date(2019, 3, 2), datetime.datetime(2019, 3, 2, 1), Decimal('200.0')),
(300, datetime.date(2019, 3, 3), datetime.datetime(2019, 3, 3, 1), Decimal('300.0')),
(400, datetime.date(2019, 3, 4), datetime.datetime(2019, 3, 4, 1), Decimal('400.0')),
]
columns = [
StructField('int_column', IntegerType()),
StructField('date_column', DateType()),
StructField('timestamp_column', TimestampType()),
StructField('decimal_column', DecimalType(10, 2)),
]
schema = StructType(columns)
spark_context = SparkContext(conf=SparkConf())
sql_context = SQLContext(spark_context)
rdd = spark_context.parallelize(data)
df = sql_context.createDataFrame(rdd, schema=schema)
db_path = '/tmp/parquet_test'
df.write.parquet(db_path, compression='gzip')
dataset = parquet.ParquetDataset(db_path)
meta_data = dataset.pieces[1].get_metadata(parquet.ParquetFile)
row_group = meta_data.row_group(0)
for col_index in range(len(columns)):
column = row_group.column(col_index)
print(f'column name: {column.path_in_schema}, is_stats_set: {column.is_stats_set}')
代码输出为:
column name: int_column, is_stats_set: True
column name: date_column, is_stats_set: True
column name: timestamp_column, is_stats_set: False
column name: decimal_column, is_stats_set: False
我不知道PySpark为什么不设置最后两列的统计信息。
我是否错过了代码中的某些内容,还是PySpark的预期行为?如果是后者,则需要我自己将时间戳转换为整数。