如何读取通过Dask保存的Parquet自定义元数据?
访问Dask保存Parquet时的自定义元数据
问题原因
Dask的custom_metadata参数默认是将元数据写入全局_metadata文件(Dask生成的汇总元数据文件),而非单个分区Parquet文件的页脚中,这就是你直接读取分区文件元数据找不到目标键值对的原因。
方法1:读取全局_metadata文件中的自定义元数据
方式A:用Dask直接读取
import dask.dataframe as dd # 读取自定义元数据 custom_meta = dd.read_parquet('parquet_folder', metadata='custom') print(custom_meta)
方式B:用PyArrow读取全局元数据文件
import pyarrow.parquet as pq # 加载全局_metadata文件 global_metadata = pq.read_metadata('parquet_folder/_metadata') # 提取自定义元数据(注意键值对以字节形式存储,需解码) target_value = global_metadata.metadata.get(b'something').decode() print(target_value) # 输出: something_else
方法2:将自定义元数据写入单个分区的Parquet页脚
如果需要把元数据写入每个分区文件的页脚,需要手动处理每个分区的写入逻辑,结合PyArrow的表元数据替换功能:
写入代码
import dask.dataframe as dd import pandas as pd import pyarrow as pa import pyarrow.parquet as pq def write_partition_with_metadata(df, output_path): # 将DataFrame转为PyArrow Table table = pa.Table.from_pandas(df) # 替换表的元数据,添加自定义内容 table = table.replace_metadata({'something': 'something_else'}) # 写入Parquet文件 pq.write_table(table, output_path) return None # 创建测试数据 df = dd.from_pandas(pd.DataFrame({'a':[1, 2], 'b':[3, 4]}), npartitions=2) # 定义每个分区的输出路径 partition_paths = [f'parquet_folder/part.{i}.parquet' for i in range(df.npartitions)] # 逐个分区写入带自定义元数据的Parquet文件 dd.compute(*[ df.get_partition(i).map_partitions(write_partition_with_metadata, output_path=partition_paths[i]) for i in range(df.npartitions) ])
读取单个分区的元数据
import pyarrow.parquet as pq # 读取单个分区的元数据 partition_metadata = pq.read_metadata('parquet_folder/part.0.parquet') # 提取并解码自定义元数据 target_value = partition_metadata.metadata.get(b'something').decode() print(target_value) # 输出: something_else
内容的提问来源于stack exchange,提问作者houseofleft
相关产品推荐
相关产品推荐

