PySpark Write Parquet Binary Column with Stats (signed-min-max.enabled)
PySpark Write Parquet Binary Column with Stats (signed-min-max.enabled)
我找到了这张 apache-parquet 票证 https://issues.apache.org/jira/browse/PARQUET-686,它被标记为 parquet-mr
1.8.2 已解决。我想要的功能是在镶木地板元数据中为(string
或 BINARY
)列计算的 min/max
。
引用这是一封电子邮件 https://lists.apache.org/thread.html/%3CCANPCBc2UPm+oZFfP9oT8gPKh_v0_BF0jVEuf=Q3d-5=ugxSFbQ@mail.gmail.com%3E
以 scala
而不是 pyspark
为例:
Configuration conf = new Configuration();
+ conf.set("parquet.strings.signed-min-max.enabled", "true");
Path inputPath = new Path(input);
FileStatus inputFileStatus =
inputPath.getFileSystem(conf).getFileStatus(inputPath);
List<Footer> footers = ParquetFileReader.readFooters(conf, inputFileStatus, false);
我一直无法在 pyspark
中设置这个值(也许我设置的地方不对?)
示例数据帧
import random
import string
from pyspark.sql.types import StringType
r = []
for x in range(2000):
r.append(u''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(10)))
df = spark.createDataFrame(r, StringType())
我尝试了几种不同的方法来设置此选项:
df.write.format("parquet").option("parquet.strings.signed-min-max.enabled", "true").save("s3a://test.bucket/option")
df.write.option("parquet.strings.signed-min-max.enabled", "true").parquet("s3a://test.bucket/option")
df.write.option("parquet.strings.signed-min-max.enabled", True).parquet("s3a://test.bucket/option")
但是所有保存的镶木地板文件都缺少 BINARY 列的 ST/STATS。以下是其中一个镶木地板文件的元数据输出示例:
creator: parquet-mr version 1.8.3 (build aef7230e114214b7cc962a8f3fc5aeed6ce80828)
extra: org.apache.spark.sql.parquet.row.metadata = {"type":"struct","fields":[{"name":"value","type":"string","nullable":true,"metadata":{}}]}
file schema: spark_schema
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
value: OPTIONAL BINARY O:UTF8 R:0 D:1
row group 1: RC:33 TS:515
---------------------------------------------------------------------------------------------------
此外,基于此电子邮件链 https://mail-archives.apache.org/mod_mbox/spark-user/201410.mbox/%3C9DEF4C39-DFC2-411B-8987-5B9C33842974@videoamp.com%3E and question:
我尝试通过 pyspark private 偷偷配置 API:
spark.sparkContext._jsc.hadoopConfiguration().setBoolean("parquet.strings.signed-min-max.enabled", True)
所以我仍然无法在 parquet-mr
中设置此 conf parquet.strings.signed-min-max.enabled
(或者它已设置,但其他地方出了问题)
- 是否可以从 pyspark
配置 parquet-mr
- pyspark 2.3.x 支持 BINARY 列统计信息吗?
- 如何利用 PARQUET-686 功能为 parquet 文件中的字符串列添加
min/max
元数据?
由于历史上 Parquet 编写者为 UTF-8 字符串编写了错误的 min/max 值,新的 Parquet 实现在读取过程中会跳过这些统计信息,除非设置了 parquet.strings.signed-min-max.enabled
。因此,此设置是一个 read 选项,它告诉 Parquet 库信任 min/max 值,尽管它们已知存在缺陷。可以安全启用此设置的唯一情况是字符串仅包含 ASCII 字符,因为这些字符的相应字节永远不会为负数。
由于您使用 parquet-tools
转储统计信息并且 parquet-tools
本身使用 Parquet 库,因此默认情况下它将忽略字符串 min/max 统计信息。虽然文件中似乎没有 min/max 值,但实际上它们在那里,但被忽略了。
此问题的正确解决方案是 PARQUET-1025,它引入了新的统计字段 min-value
和 max-value
。这些可以正确处理 UTF-8 字符串。
我找到了这张 apache-parquet 票证 https://issues.apache.org/jira/browse/PARQUET-686,它被标记为 parquet-mr
1.8.2 已解决。我想要的功能是在镶木地板元数据中为(string
或 BINARY
)列计算的 min/max
。
引用这是一封电子邮件 https://lists.apache.org/thread.html/%3CCANPCBc2UPm+oZFfP9oT8gPKh_v0_BF0jVEuf=Q3d-5=ugxSFbQ@mail.gmail.com%3E
以 scala
而不是 pyspark
为例:
Configuration conf = new Configuration(); + conf.set("parquet.strings.signed-min-max.enabled", "true"); Path inputPath = new Path(input); FileStatus inputFileStatus = inputPath.getFileSystem(conf).getFileStatus(inputPath); List<Footer> footers = ParquetFileReader.readFooters(conf, inputFileStatus, false);
我一直无法在 pyspark
中设置这个值(也许我设置的地方不对?)
示例数据帧
import random
import string
from pyspark.sql.types import StringType
r = []
for x in range(2000):
r.append(u''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(10)))
df = spark.createDataFrame(r, StringType())
我尝试了几种不同的方法来设置此选项:
df.write.format("parquet").option("parquet.strings.signed-min-max.enabled", "true").save("s3a://test.bucket/option")
df.write.option("parquet.strings.signed-min-max.enabled", "true").parquet("s3a://test.bucket/option")
df.write.option("parquet.strings.signed-min-max.enabled", True).parquet("s3a://test.bucket/option")
但是所有保存的镶木地板文件都缺少 BINARY 列的 ST/STATS。以下是其中一个镶木地板文件的元数据输出示例:
creator: parquet-mr version 1.8.3 (build aef7230e114214b7cc962a8f3fc5aeed6ce80828)
extra: org.apache.spark.sql.parquet.row.metadata = {"type":"struct","fields":[{"name":"value","type":"string","nullable":true,"metadata":{}}]}
file schema: spark_schema
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
value: OPTIONAL BINARY O:UTF8 R:0 D:1
row group 1: RC:33 TS:515
---------------------------------------------------------------------------------------------------
此外,基于此电子邮件链 https://mail-archives.apache.org/mod_mbox/spark-user/201410.mbox/%3C9DEF4C39-DFC2-411B-8987-5B9C33842974@videoamp.com%3E and question:
我尝试通过 pyspark private 偷偷配置 API:
spark.sparkContext._jsc.hadoopConfiguration().setBoolean("parquet.strings.signed-min-max.enabled", True)
所以我仍然无法在 parquet-mr
中设置此 conf parquet.strings.signed-min-max.enabled
(或者它已设置,但其他地方出了问题)
- 是否可以从 pyspark 配置
- pyspark 2.3.x 支持 BINARY 列统计信息吗?
- 如何利用 PARQUET-686 功能为 parquet 文件中的字符串列添加
min/max
元数据?
parquet-mr
由于历史上 Parquet 编写者为 UTF-8 字符串编写了错误的 min/max 值,新的 Parquet 实现在读取过程中会跳过这些统计信息,除非设置了 parquet.strings.signed-min-max.enabled
。因此,此设置是一个 read 选项,它告诉 Parquet 库信任 min/max 值,尽管它们已知存在缺陷。可以安全启用此设置的唯一情况是字符串仅包含 ASCII 字符,因为这些字符的相应字节永远不会为负数。
由于您使用 parquet-tools
转储统计信息并且 parquet-tools
本身使用 Parquet 库,因此默认情况下它将忽略字符串 min/max 统计信息。虽然文件中似乎没有 min/max 值,但实际上它们在那里,但被忽略了。
此问题的正确解决方案是 PARQUET-1025,它引入了新的统计字段 min-value
和 max-value
。这些可以正确处理 UTF-8 字符串。