【发布时间】:2021-12-03 06:33:48
【问题描述】:
用例是将列附加到 Parquet 数据集,然后在同一位置有效地重写。这是一个最小的例子。
创建一个pandas DataFrame 并作为分区 Parquet 数据集写入。
import pandas as pd
df = pd.DataFrame({
'id': ['a','a','a','b','b','b','b','c','c'],
'value': [0,1,2,3,4,5,6,7,8]})
path = r'c:/data.parquet'
df.to_parquet(path=path, engine='pyarrow', compression='snappy', index=False, partition_cols=['id'], flavor='spark')
然后将 Parquet 数据集加载为 pyspark 视图,并将修改后的数据集创建为 pyspark DataFrame。
from pyspark.sql import SparkSession
spark = SparkSession.builder.getOrCreate()
spark.read.parquet(path).createTempView('data')
sf = spark.sql(f"""SELECT id, value, 0 AS segment FROM data""")
此时sf 数据与df 数据相同,但有一个额外的全为零的segment 列。我想用sf 有效地覆盖path 的现有Parquet 数据集,作为同一位置的Parquet 数据集。下面是什么不起作用。也不愿将sf 写入新位置,删除旧的 Parquet 数据集,并重命名为似乎效率不高。
# saves existing data and new data
sf.write.partitionBy('id').mode('append').parquet(path)
# immediately deletes existing data then crashes
sf.write.partitionBy('id').mode('overwrite').parquet(path)
【问题讨论】:
-
该问题没有公认的答案,只是建议重新编写整个数据集然后删除可能引入大量开销的原始数据集,或者加载到内存然后覆盖,这可能并不总是规模。
标签: python apache-spark pyspark apache-spark-sql parquet