如何用PySpark读取带通配符的HDFS Parquet文件?
解决Spark读取Parquet时通配符不生效的问题
嘿,我来帮你搞定这个问题!首先咱们得先搞清楚为什么你原来的写法不行,然后给你几个靠谱的解决方案:
问题根源
你原来的代码df = spark.read.parquet('/a/b/c='*'/d='str')存在两个核心问题:
- 语法错误:在Python中,单引号包裹的字符串里如果直接出现单引号,会提前终止字符串,导致
*被当成了字符串外的语法元素,Python根本无法正确解析这个路径。 - 通配符匹配逻辑问题:即使语法没问题,这种针对分区目录的通配符写法也不够稳妥,容易出现解析偏差。
解决方案
这里给你三种可行的办法,按需选择:
1. 正确处理路径中的单引号,使用通配符
你可以通过转义单引号,或者改用双引号包裹整个路径字符串,让Python正确识别通配符:
# 方式1:转义单引号(适合用单引号包裹路径的场景) df = spark.read.parquet('/a/b/c=\'*\'/d=\'str\'') # 方式2:用双引号包裹整个路径(更简洁直观) df = spark.read.parquet("/a/b/c='*'/d='str'")
2. 利用Spark自动分区发现(推荐!性能更好)
你的路径是典型的分区表结构(c和d是分区列),Spark默认会自动识别这些分区列,所以你完全不用手动写通配符,直接读取父目录再过滤即可:
# 读取父目录,Spark会自动识别c、d作为分区列 df = spark.read.parquet('/a/b') # 过滤出d='str'的所有分区数据(SQL风格语法) df = df.filter("d = 'str'") # 或者用Python风格的过滤语法 df = df.filter(df.d == 'str')
这种方式的优势在于Spark会自动做分区裁剪(Partition Pruning),只读取符合条件的分区数据,比用通配符的性能更高。
3. 简化通配符写法,匹配整个子目录
既然c='str1'、c='str2'都是/a/b下的直接子目录,你可以直接用*匹配所有这些子目录,避开单引号的处理麻烦:
df = spark.read.parquet('/a/b/*/d=\'str\'')
内容的提问来源于stack exchange,提问作者Frank
相关产品推荐
相关产品推荐

